From 834fcc1bd5f000345c531837b01d26da16f65a4a Mon Sep 17 00:00:00 2001 From: Sergei Trofimov Date: Tue, 20 Aug 2024 17:10:39 +0100 Subject: [PATCH] doc: update end-to-end/walkthrough.md Update the end-to-end walkthrough to reflect the latest changes to the code line, and to improve its maintainability going forward. - Mention native deployment as an alternative to Docker. - Remove the installation instructions, pointing to the deployments' READMEs instead, and only giving the actual make command. - Remove references to external `cocli` and `evcli` tools, instead relying on the ones that are part of the deployment and on the JSON "templates" that are part of this code base. This way, there is no risk of things getting out of sync. - Remove relative paths from commands, instead using pre-defined root locations. This removes ambiguity as to where things are (are paths relative to the file, to the repo, PWD, etc), and make commands more robust when being executed via copying and pasting, as they won't rely on PWD. - Adjust the instructions so that no new files are created or existing files modified in the source-controlled repo. Instead use a dedicated working directory created as part of the walkthrough for any new or modified files. This makes it clearer afterwards what was changed/crated, and reduced the possibility of stray changes being committed. - Update CoRIM/CoMID "template" listings to reflect the updated formats. - Reformat for readability and consistency with the rest of documentation: 79 column lines, use ```sh for shell listings. - Minor typo fixes. In addition to the walkthrough itself, the following related updates are included: - Update end-to-end inputs build script to build evidence, as well as corims from source. - Update deployments' READMEs to include "git clone" followed by "cd" as part of the initial listing to give better context to where the rest of the commands in the READMEs are supposed to be executed. Signed-off-by: Sergei Trofimov --- deployments/docker/README.md | 101 ++- deployments/native/README.md | 3 + end-to-end/input/cca-evidence.cbor | Bin 1382 -> 1382 bytes end-to-end/input/psa-evidence.cbor | Bin 546 -> 546 bytes .../build-inputs.sh} | 10 + end-to-end/input/src/cca-evidence.json | 51 ++ .../comid-cca-realm-refval.json | 0 .../{corim-src => src}/comid-cca-refval.json | 0 .../{corim-src => src}/comid-cca-ta.json | 0 .../{corim-src => src}/comid-psa-refval.json | 0 .../{corim-src => src}/comid-psa-ta.json | 0 .../{corim-src => src}/corim-cca-realm.json | 0 .../input/{corim-src => src}/corim-cca.json | 0 .../input/{corim-src => src}/corim-psa.json | 0 end-to-end/input/src/psa-evidence.json | 31 + end-to-end/walkthrough.md | 720 +++++++++++------- 16 files changed, 614 insertions(+), 302 deletions(-) rename end-to-end/input/{corim-src/build-endorsements.sh => src/build-inputs.sh} (67%) create mode 100644 end-to-end/input/src/cca-evidence.json rename end-to-end/input/{corim-src => src}/comid-cca-realm-refval.json (100%) rename end-to-end/input/{corim-src => src}/comid-cca-refval.json (100%) rename end-to-end/input/{corim-src => src}/comid-cca-ta.json (100%) rename end-to-end/input/{corim-src => src}/comid-psa-refval.json (100%) rename end-to-end/input/{corim-src => src}/comid-psa-ta.json (100%) rename end-to-end/input/{corim-src => src}/corim-cca-realm.json (100%) rename end-to-end/input/{corim-src => src}/corim-cca.json (100%) rename end-to-end/input/{corim-src => src}/corim-psa.json (100%) create mode 100644 end-to-end/input/src/psa-evidence.json diff --git a/deployments/docker/README.md b/deployments/docker/README.md index 077fedc2..a959c9f7 100644 --- a/deployments/docker/README.md +++ b/deployments/docker/README.md @@ -1,6 +1,21 @@ This directory contains the [Docker](https://www.docker.com/) source for the -deployment of Veraison. In order to build it, you need to have Docker -installed, and current user must be in the docker group. +deployment of Veraison. + +## Dependencies + +You will need to make sure you have `make`, `git`, `docker` (and its builder), +and `jq` installed on your system. Optionally, `tmux` can be used to +conveniently monitor output from running services. The CLI front-end relies on +`bash` shell, which should already be installed most systems, but if not, it +would also need to be installed. + +```sh +# on Ubuntu +sudo apt install bash make git docker.io docker-buildx jq tmux + +# on Arch +sudo pacman -S bash make git docker docker-buildx jq tmux +``` > **Warning** for `Ubuntu` users: > Make sure you have docker installed natively (via `sudo apt @@ -9,29 +24,65 @@ installed, and current user must be in the docker group. > locations via the config, however we cannot guarantee that there won't be > other issues -- if you decide to stick with `snap`, you're on your own. +### Docker set up + +If you're not already set up to use Docker on your system, you will need to +make sure that it is enabled and running, and that you can access by adding +your account to the `docker` group: + +```sh +sudo systemctl enable --now docker +sudo usrmod -a -G docker $USER +``` + +The user group modification won't take effect until you log out and log back +in, or, alternatively, you can force in a specific shell with + +```sh +newgrp docker +``` + +## Creating the Deployment + Once you have the pre-requisites, you can create the deployment on your local -system simply by running +system - make +```sh +git clone https://github.com/veraison/services.git +cd services/deployments/docker + +make +``` Once the deployment is created, you can set up the front end by executing - source env.bash +```sh +source env.bash +``` -Inside a bash shell. There is an equivalent `env.zsh` for zsh (other shells are +inside a bash shell. There is an equivalent `env.zsh` for zsh (other shells are currently not supported). You can interact with the deployment via the `veraison` command. E.g.: - $ veraison status - vts: stopped - provisioning: stopped - verification: stopped - management: stopped - keycloak: stopped +```sh +veraison status +``` + +You should see output similar to + +``` + vts: stopped +provisioning: stopped +verification: stopped + management: stopped + keycloak: stopped +``` To start Veraison services run: - veraison start +```sh +veraison start +``` The provisioning service is now listening on port 8888, and verification service on port 8080 (these can be changed via configuration -- see below). @@ -116,14 +167,18 @@ First, assuming you have frontend set up, and the services running, (if not, you can do so with `source env.bash; veraison start`), you will need to stop the "production" VTS service with: - veraison stop vts +```sh +veraison stop vts +``` this will stop `vts-service` but should leave the other services running (you can verify that by running `veraison status`). Next, enter the debug shell: - make DEBUG_HOST=vts-service debug +```sh +make DEBUG_HOST=vts-service debug +``` this will pop open a `bash` shell inside the builder. The `DEBUG_HOST` argument will set the hostname of the builder container. Here, we're setting it to the @@ -139,9 +194,11 @@ Next, navigate to the location of the VTS service executable (keeping in mind that the root of the repo is mapped to `/veraison/build` inside the container), and start the debugger: - # inside the debug shell: - cd /veraison/build/vts/cmd/vts-service - debug +```sh +# inside the debug shell: +cd /veraison/build/vts/cmd/vts-service +debug +``` The `debug` command is an alias for `dlv debug` that will make sure that the debug executable will be built with evidence handling plugins compiled in (same @@ -158,6 +215,8 @@ that, so you don't need to worry about it. However, if you want to run the service executable directly, then you must remember to specify the appropriate config, e.g. - # inside the debug shell: - cd /veraison/build/vts/cmd/vts-service - ./veraison-service --config config-docker.yaml +```sh +# inside the debug shell: +cd /veraison/build/vts/cmd/vts-service +./vts-service --config config-docker.yaml +``` diff --git a/deployments/native/README.md b/deployments/native/README.md index 72af9b03..9a83a350 100644 --- a/deployments/native/README.md +++ b/deployments/native/README.md @@ -55,6 +55,9 @@ Arch, Ubuntu, and MacOSX (using [homebrew](https://brew.sh)) (see `bootstrap/` subdirectory). Running ```bash +git clone https://github.com/veraison/services.git +cd services/deployments/native + make bootstrap ``` diff --git a/end-to-end/input/cca-evidence.cbor b/end-to-end/input/cca-evidence.cbor index b5c55e5941f5082da60aa188676de670c74d48bb..be8061897485c04e3abcfea9650467b7a7797c6f 100644 GIT binary patch delta 174 zcmV;f08#(u3g!y1T>?PLeljZz^|5VegD>A7tV-#Q*93BFg4l7XpT5nz$wE)@({^t-0(`7U|NQ$or2dF>YLKDodRhBV2*b!DzPOVX_)O;I4tNqPD~&~ zzA^T!UPvDYk-F$X7$nX+VmyX*w;Tq|SGZOFp=Ltj7qyaEEwuw)<@8Wf#5BUC@DADL cOEIhm`A|ich5uUO#nIxZWf-U-b2YC(u*Zc~#sB~S delta 174 zcmV;f08#(u3g!y1T>?PdWvU=Q2Acu;V!T!`f|mf?Hn9X5vz?97Ae2Bln!^Gg@O)X- zxst>X`T+%J;|DV0?&Fvm35`_g8LD@)>e&#podRhBVEr{;Ue#d;fDZmD%Xvibi;gVH z%$3XMRbhS;^C1L?rs%Iv41|A!WAvHmtLQq%<2OBsIr}kNe5P#4R9~cLNMA3|NfZ;z c@`GdtzMv4m`??6v-0|@Z3K#cIdDNB*j^}Hlxm%{P`9sYBc6-_wjF0Gy^lRKlM1ZhQfe8pGc eb;8I-u3;&BB^*2i%HErFkID9+%Le7LPWY8RZy^Z) diff --git a/end-to-end/input/corim-src/build-endorsements.sh b/end-to-end/input/src/build-inputs.sh similarity index 67% rename from end-to-end/input/corim-src/build-endorsements.sh rename to end-to-end/input/src/build-inputs.sh index 8c7ff3e8..d5aeb8c6 100755 --- a/end-to-end/input/corim-src/build-endorsements.sh +++ b/end-to-end/input/src/build-inputs.sh @@ -1,6 +1,7 @@ #!/bin/bash # Copyright 2024 Contributors to the Veraison project. # SPDX-License-Identifier: Apache-2.0 +# shellcheck disable=SC2086 set -e TEMP_DIR=/tmp/veraison-end-to-end @@ -18,3 +19,12 @@ for scheme in psa cca cca-realm; do --output ${SCRIPT_DIR}/../${scheme}-endorsements.cbor done +evcli psa create --claims ${SCRIPT_DIR}/psa-evidence.json \ + --key ${SCRIPT_DIR}/../ec256.json \ + --token ${SCRIPT_DIR}/../psa-evidence.cbor + +evcli cca create --claims ${SCRIPT_DIR}/cca-evidence.json \ + --iak ${SCRIPT_DIR}/../ec256.json --rak ${SCRIPT_DIR}/../ec384.json \ + --token ${SCRIPT_DIR}/../cca-evidence.cbor + +echo "done." diff --git a/end-to-end/input/src/cca-evidence.json b/end-to-end/input/src/cca-evidence.json new file mode 100644 index 00000000..a52cb660 --- /dev/null +++ b/end-to-end/input/src/cca-evidence.json @@ -0,0 +1,51 @@ +{ + "cca-platform-token": { + "cca-platform-profile": "http://arm.com/CCA-SSD/1.0.0", + "cca-platform-implementation-id": "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=", + "cca-platform-instance-id": "AQICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC", + "cca-platform-config": "AQID", + "cca-platform-lifecycle": 12288, + "cca-platform-sw-components": [ + { + "measurement-type": "BL", + "measurement-value": "BwYFBAMCAQAPDg0MCwoJCBcWFRQTEhEQHx4dHBsaGRg=", + "signer-id": "BwYFBAMCAQAPDg0MCwoJCBcWFRQTEhEQHx4dHBsaGRg=", + "version": "3.4.2" + }, + { + "measurement-type": "M1", + "measurement-value": "CwYFBAMCAQAPDg0MCwoJCBcWFRQTEhEQHx4dHBsaGRg=", + "signer-id": "BwYFBAMCAQAPDg0MCwoJCBcWFRQTEhEQHx4dHBsaGRg=", + "version": "1.2.0" + }, + { + "measurement-type": "M2", + "measurement-value": "DwYFBAMCAQAPDg0MCwoJCBcWFRQTEhEQHx4dHBsaGRg=", + "signer-id": "BwYFBAMCAQAPDg0MCwoJCBcWFRQTEhEQHx4dHBsaGRg=", + "version": "1.2.3" + }, + { + "measurement-type": "M3", + "measurement-value": "EwYFBAMCAQAPDg0MCwoJCBcWFRQTEhEQHx4dHBsaGRg=", + "signer-id": "BwYFBAMCAQAPDg0MCwoJCBcWFRQTEhEQHx4dHBsaGRg=", + "version": "1.0.0" + } + ], + "cca-platform-service-indicator": "https://veraison.example/v1/challenge-response", + "cca-platform-hash-algo-id": "sha-256" + }, + "cca-realm-delegated-token": { + "cca-realm-challenge": "QUJBQkFCQUJBQkFCQUJBQkFCQUJBQkFCQUJBQkFCQUJBQkFCQUJBQkFCQUJBQkFCQUJBQkFCQUJBQkFCQUJBQg==", + "cca-realm-personalization-value": "QURBREFEQURBREFEQURBREFEQURBREFEQURBREFEQURBREFEQURBREFEQURBREFEQURBREFEQURBREFEQURBRA==", + "cca-realm-initial-measurement": "Q0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQw==", + "cca-realm-extensible-measurements": [ + "Q0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQw==", + "Q0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQw==", + "Q0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQw==", + "Q0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQw==" + ], + "cca-realm-hash-algo-id": "sha-256", + "cca-realm-public-key": "BIL70TKptcOWh5+7FTQNkFCXjlXHnVJ5oroOlYVPN+IM0vZPO3K1cLvXc+7iznaEJe31Re2+if+v4OlrvUbicPIHlsRIuY2vRqdk0nRC5ubthPjOyBfm7ManHTo959Z+zQ==", + "cca-realm-public-key-hash-algo-id": "sha-512" + } +} diff --git a/end-to-end/input/corim-src/comid-cca-realm-refval.json b/end-to-end/input/src/comid-cca-realm-refval.json similarity index 100% rename from end-to-end/input/corim-src/comid-cca-realm-refval.json rename to end-to-end/input/src/comid-cca-realm-refval.json diff --git a/end-to-end/input/corim-src/comid-cca-refval.json b/end-to-end/input/src/comid-cca-refval.json similarity index 100% rename from end-to-end/input/corim-src/comid-cca-refval.json rename to end-to-end/input/src/comid-cca-refval.json diff --git a/end-to-end/input/corim-src/comid-cca-ta.json b/end-to-end/input/src/comid-cca-ta.json similarity index 100% rename from end-to-end/input/corim-src/comid-cca-ta.json rename to end-to-end/input/src/comid-cca-ta.json diff --git a/end-to-end/input/corim-src/comid-psa-refval.json b/end-to-end/input/src/comid-psa-refval.json similarity index 100% rename from end-to-end/input/corim-src/comid-psa-refval.json rename to end-to-end/input/src/comid-psa-refval.json diff --git a/end-to-end/input/corim-src/comid-psa-ta.json b/end-to-end/input/src/comid-psa-ta.json similarity index 100% rename from end-to-end/input/corim-src/comid-psa-ta.json rename to end-to-end/input/src/comid-psa-ta.json diff --git a/end-to-end/input/corim-src/corim-cca-realm.json b/end-to-end/input/src/corim-cca-realm.json similarity index 100% rename from end-to-end/input/corim-src/corim-cca-realm.json rename to end-to-end/input/src/corim-cca-realm.json diff --git a/end-to-end/input/corim-src/corim-cca.json b/end-to-end/input/src/corim-cca.json similarity index 100% rename from end-to-end/input/corim-src/corim-cca.json rename to end-to-end/input/src/corim-cca.json diff --git a/end-to-end/input/corim-src/corim-psa.json b/end-to-end/input/src/corim-psa.json similarity index 100% rename from end-to-end/input/corim-src/corim-psa.json rename to end-to-end/input/src/corim-psa.json diff --git a/end-to-end/input/src/psa-evidence.json b/end-to-end/input/src/psa-evidence.json new file mode 100644 index 00000000..8e588f43 --- /dev/null +++ b/end-to-end/input/src/psa-evidence.json @@ -0,0 +1,31 @@ +{ + "eat-profile": "http://arm.com/psa/2.0.0", + "psa-client-id": 1, + "psa-security-lifecycle": 12288, + "psa-implementation-id": "YWNtZS1pbXBsZW1lbnRhdGlvbi1pZC0wMDAwMDAwMDE=", + "psa-boot-seed": "3q2+796tvu/erb7v3q2+796tvu/erb7v3q2+796tvu8=", + "psa-hardware-version": "1234567890123", + "psa-software-components": [ + { + "measurement-type": "BL", + "measurement-value": "h0KPxSKAPTEGXnvOPPA/5HUJZjHl4Hu9eg/eYMTPJcc=", + "signer-id": "rLsRx+TaIXIFUjzkzhokWuGiOa48a/2eeHH35di66Gs=", + "version": "2.1.0" + }, + { + "measurement-type": "PRoT", + "measurement-value": "AmOCmYm2/ZVPcrqvL8ZLwuLwHWktTecphuqAj26ZgT8=", + "signer-id": "rLsRx+TaIXIFUjzkzhokWuGiOa48a/2eeHH35di66Gs=", + "version": "1.3.5" + }, + { + "measurement-type": "ARoT", + "measurement-value": "o6XnFfDMV0pzw/m+u2vCTzL/1bZ7OHJEwskJ2neaFHg=", + "signer-id": "rLsRx+TaIXIFUjzkzhokWuGiOa48a/2eeHH35di66Gs=", + "version": "0.1.4" + } + ], + "psa-instance-id": "Ac7rrnuJJ6MiflMDz14PH3s0u1Qq1yUKwD+83jbsLxUI", + "psa-verification-service-indicator": "https://psa-verifier.org", + "psa-nonce": "QUp8F0FBs9DpodKK8xUg8NQimf6sQAfe2J1ormzZLxk=" +} diff --git a/end-to-end/walkthrough.md b/end-to-end/walkthrough.md index 0d344e55..9e3e83b0 100644 --- a/end-to-end/walkthrough.md +++ b/end-to-end/walkthrough.md @@ -1,109 +1,183 @@ -# Attestation Walkthough +# Attestation Walkthrough -This guide explains how to setup a verifier and an attester. To produce a workable example setup, it is necessary to +This guide explains how to setup a verifier and an attester. To produce a +workable example setup, it is necessary to - create attestation keys on the attester, -- provisioning trust anchors, reference values and endorsements on the verifier, and +- provisioning trust anchors, reference values and endorsements on the + verifier, and - to create evidence on the attester for consumption by the verifier. -For this example setup evidence is provided in form of an PSA attestation token. +For this example setup evidence is provided in form of an PSA attestation +token. -## Software Dependencies +## Dependencies -The software depends at least on +The dependencies required to run Veraison on your system depend on whether you are +using a native or Docker deployment. Please refer to the appropriate README +(see below) for details. -- Docker X, and -- Go +In addition, this walkthrough relies on the following: -Veraison also has additional dependencies, which are described at https://github.com/veraison/services +- `go` compiler (even if using Docker) will be used to install additional tools +- `openssl` to generate keys +- `jq` is used for modifying JSON files (optional: you can use text editor + instead). +- `wget` to fetch the verifier key. -> **Important**: Do not install Docker Desktop (at least on Ubuntu) since otherwise Veraison build will fail. +```sh +# on Ubuntu +sudo apt install golang-go openssl jq wget -Use the following command to install the dependencies for Veraison on an Ubuntu OS: +# on Arch +sudo pacman -S go openssl jq wget +``` -~~~bash -sudo apt install git docker.io jq tmux docker-buildx -~~~ +(note: some of these may already be installed on your system) -## Veraison +## Installing and running Veraison + +You have two options for running Veraison on your local system: either +[natively](../deployments/native/README.md) or [via +Docker](../deployments/docker/README.md). Please refer to the linked READMEs for +detailed requirements and steps. -This section provides details about the use of the Veraison docker image, which is meant to be used for demo purposes. The repository of Veraison can be found at https://github.com/veraison/services +> [!NOTE] +> Commands in listings below will make use of the following locations (all of +> them will be set before they are first used): +> - `VERAISON_SRC`: the location of Veraison source +> - `VERAISON_ROOT`: the location of the Veraison native deployment (only if +> using native deployment, not used for Docker deployment). +> - `WORK_DIR`: directory used for artifacts generated during this walkthrough. -In summary, the following steps need to be executed. Note that these steps assume the use of the bash shell. +If you have the prerequisites satisfied, you can create a deployment with -~~~bash +```sh git clone https://github.com/veraison/services.git -cd services -make docker-deploy +export VERAISON_SRC=$PWD/services + +# For Docker deployment +make -C $VERAISON_SRC docker-deploy + +# Alternatively, for native deployment +make -C $VERAISON_SRC native-deploy +``` + +The rest of this document assumes that you have the `env.bash` (or `env.zsh`) +for the deployment sourced in your shell. -source deployments/docker/env.bash +```sh +# For docker deployment (inside top-level source directory) +source $VERAISON_SRC/deployments/docker/env.bash + +# For native deployment +export VERAISON_ROOT=~/veraison-deployment # default location +source $VERAISON_ROOT/env/env.bash + +``` + +## Veraison + +You can check the status of the deployment with + +```sh veraison status -~~~ +``` -If Veraison services are not running, then they need to be started with the following command: +If Veraison services are not running, then they need to be started with the +following command: -~~~bash +```sh veraison start -~~~ +``` To check the status of the database use the following command: -~~~bash +```sh veraison check-stores -~~~ +``` -Of course, after the initial installation, the database will be empty. The provisioning of reference values, trust anchors and endosements will -be explained below and those will be stored in the database. If you haven't created attestation keys yet, first look at the next section otherwise skip it. +Of course, after the initial installation, the database will be empty. The +provisioning of reference values, trust anchors and endorsements will be +explained below and those will be stored in the database. If you haven't +created attestation keys yet, first look at the next section otherwise skip it. -In case of problems, use the following command (in a separate command line window) to see the log output. +In case of problems, use the following command (in a separate command line +window) to see the log output. -~~~bash +```sh veraison follow -~~~ +``` -Replace `` with one of the services available with Veraison, namely `vts`, `provisioning`, `verification`, `management`, or `keycloak`. +Replace `` with one of the services available with Veraison, +namely `vts`, `provisioning`, `verification`, `management`, or (for Docker +deployment) `keycloak`. -Debug output can be enabled by changing the log level inside `deployments/docker/src/config.yaml.template` before creating the deployment (i.e. running `make docker-deploy`; if a deployment already exists `make really-clean` should be done first). See also https://github.com/veraison/services/tree/main/deployments/docker#debugging for more detailed instructions on how to debug a specific service. +For Docker deployment, debug output can be enabled by changing the log level +inside `${VERAISON_SRC}/deployments/docker/src/config.yaml.template` before +creating the deployment (i.e. running `make docker-deploy`; if a deployment +already exists `make really-clean` should be done first). See also +https://github.com/veraison/services/tree/main/deployments/docker#debugging for +more detailed instructions on how to debug a specific service. -Sometimes it is necessary to remove the content of the database. In this case, run the following command. +For native deployment, debug output can be enabled by changing the log level +inside `${VERAISON_ROOT}/config/sevices/config.yaml`. For this to take effect, +the services will need to be restarted, `veraison stop && veraison start`. -~~~bash +Sometimes it is necessary to remove the content of the database. In this case, +run the following command. + +```sh veraison clear-stores -~~~ +``` -To completely remove the deployment and remove the build artifacts use the following command. Note that this requires you to re-run `make docker-deploy` if you want to use Veraison again. +To completely remove the deployment and remove the build artifacts use the +following command. Note that this requires you to re-run `make -C $VERAISON_SRC +docker-deploy` if you want to use Veraison again. -~~~bash -make -C ../deployments/docker really-clean -~~~ +```sh +make -C $VERAISON_SRC really-clean +``` ## Creating an Attestation Key for the Attester -Attesters need to have an attestation key to sign attestation Evidence. If this key is not yet available, here are instructions for creating it. -It is also necessary to convert the keys into the JSON Web Key (JWK) format and a separate tool is used for this transcoding. +Attesters need to have an attestation key to sign attestation Evidence. If this +key is not yet available, here are instructions for creating it. It is also +necessary to convert the keys into the JSON Web Key (JWK) format and a separate +tool is used for this transcoding. To start, we create a private key in PEM format using the following command: -~~~bash -openssl genpkey -algorithm ec -pkeyopt ec_paramgen_curve:prime256v1 -out key.pem -~~~ +```sh +export WORK_DIR=$PWD/walkthrough +mkdir $WORK_DIR + +openssl genpkey -algorithm ec -pkeyopt ec_paramgen_curve:prime256v1 \ + -out $WORK_DIR/key.pem +``` -We use the `go-pem2jwk` tool to convert the PEM-encoded private key into a JWK. First, we need to obtain the tool. +We use the `go-pem2jwk` tool to convert the PEM-encoded private key into a JWK. +First, we need to obtain the tool. -~~~bash +```sh go install github.com/thomas-fossati/go-pem2jwk@latest -~~~ -The go-pem2jwk tool can convert a key in PEM format into a JWK using the following command: +# add the location go installs into to PATH if it's not there already +export PATH=$(go env GOPATH)/bin:$PATH +``` -~~~bash -go-pem2jwk < key.pem > jwk.json -~~~ +The go-pem2jwk tool can convert a key in PEM format into a JWK using the +following command: -GitHub will complain if we show the PEM-encoded private key. Hence, we only print the JWT containing the private key for this example. -You are supposed to create your private key for your example setup. +```sh +go-pem2jwk < $WORK_DIR/key.pem > $WORK_DIR/jwk.json +``` -~~~json +GitHub will complain if we show the PEM-encoded private key. Hence, we only +print the JWT containing the private key for this example. You are supposed to +create your private key for your example setup. + +```json { "crv": "P-256", "d": "-fVWtEiKGbVk1J92WRwCefa78RohjMUBVKRfKARMFSQ", @@ -111,99 +185,124 @@ You are supposed to create your private key for your example setup. "x": "Oq7AxYePubv1b3bhcszgwycyDKDBvIRL400LA4xoJWA", "y": "eXVOAz4k28xU4ylyQszt6CorQ7_EQdutFjDYSLRiUG4" } -~~~ +``` Next, we create a public key based on the private key using the following command: -~~~bash -openssl ec -in key.pem -pubout -outform pem -out cert.pub -~~~ +```sh +openssl ec -in $WORK_DIR/key.pem -pubout -outform pem -out $WORK_DIR/cert.pub +``` The resulting public key in PEM format is: -~~~ +``` -----BEGIN PUBLIC KEY----- MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEOq7AxYePubv1b3bhcszgwycyDKDB vIRL400LA4xoJWB5dU4DPiTbzFTjKXJCzO3oKitDv8RB260WMNhItGJQbg== -----END PUBLIC KEY----- -~~~ +``` We also convert the PEM-encoded public key to a JWK: -~~~ -go-pem2jwk < cert.pub > pub.json -~~~ +``` +go-pem2jwk < $WORK_DIR/cert.pub > $WORK_DIR/pub.json +``` The result is shown below: -~~~json +```json { "crv": "P-256", "kty": "EC", "x": "Oq7AxYePubv1b3bhcszgwycyDKDBvIRL400LA4xoJWA", "y": "eXVOAz4k28xU4ylyQszt6CorQ7_EQdutFjDYSLRiUG4" } -~~~ +``` ## Provisioning Trust Anchors, Reference Values and Endorsements -The Verifier must be provisioned with trust anchors, reference values, and endorsements before it can be used. The `cocli` tool offers this functionality and supports several subcommands: +The Verifier must be provisioned with trust anchors, reference values, and +endorsements before it can be used. The `cocli` tool offers this functionality +and supports several subcommands: - `comid` to create, display and validate Concise Module Identifiers (CoMIDs) - `cots` to create, display and validate Concise TA Stores (CoTSs) -- `corim` to create, display, sign, and verify CoRIMs +- `corim` to create, display, sign, and verify CoRIMs -See also the [detailed documentation](https://github.com/veraison/corim/tree/main/cocli#readme) on the `veraison/corim` repository. +See also the [detailed +documentation](https://github.com/veraison/corim/blob/main/cocli/README.md) in the +`github.com/veraison/corim` repository. -~~~bash -go install github.com/veraison/corim/cocli@latest -~~~ +The `cocli` tool is part of Veraison deployment, and, provided you've sourced +`env.bash`/`env.zsh`, should be aliased in your shell with appropriate +configuration. -The concepts are described in separate IETF drafts, which are still work in progress. +The concepts are described in separate IETF drafts, which are still work in +progress. -- CoTSs are explained in https://datatracker.ietf.org/doc/draft-ietf-rats-concise-ta-stores/ +- CoTSs are explained in + https://datatracker.ietf.org/doc/draft-ietf-rats-concise-ta-stores/ -- CoRIMs and CoMIDs are described in https://datatracker.ietf.org/doc/draft-ietf-rats-corim/ +- CoRIMs and CoMIDs are described in + https://datatracker.ietf.org/doc/draft-ietf-rats-corim/ The payloads are encoded in CBOR. -It is useful to clone the `veraison/corim` repository, which contains examples. The command is: - -~~~bash -git clone https://github.com/veraison/corim.git -~~~ - -In the subsequent steps, we will create the CBOR-based payloads for submission to Veraison using a RESTful API. -Hence, we will have to create a CoMID for the reference value and a CoTS for the trust anchor. - -The command line tool, `cocli`, uses so-called templates as input to generate the CBOR files. For completeness, -the JSON files are shown below. - -The first command creates a CoMID based on two input files, one for trust anchors and another one for reference values. -The `comid-psa-ta.json` file contains information about the trust anchor(s) and the `comid-psa-refval.json` file contains -the reference value(s). - -In our example, we need to provision the public key of the Attester to Veraison. This allows Veraison to verify the -digital signature covering the Evidence (and the PSA attestation token in our case). - -The Evidence, which we will create later in this walkthrough, contains the hashes of the bootloader (BL), the PSA Root of Trust (PRoT) and the Application Root of Trust (ARoT). -The details of these software components are explained in https://datatracker.ietf.org/doc/draft-tschofenig-rats-psa-token/ -The goal is to provision the "reference" or "golden values" of these hashes to the Verifier. This allows the Verifier to match the Evidence claims sent by the Attester with the expected values. - -~~~bash -cocli comid create --template comid-psa-ta.json \ - --template comid-psa-refval.json \ - --output-dir tmp -~~~ - -The public key, which we previously created, has to be copied into the `comid-psa-ta.json` file of the `verification-keys` field. Search for the `BEGIN PUBLIC KEY` section in the JSON file below. -The UEID field contains information about the specific instance of the device and serves as a key identifier. Hence, this instance ID has to match the Instance ID claim in the Evidence. -The Implementation ID claim uniquely identifies the implementation of the immutable PSA RoT. Veraison uses this claim to locate the details of the PSA RoT implementation. The Implementation ID is also -found in the Evidence claims. - -comid-psa-ta.json: - -~~~json +In the subsequent steps, we will create the CBOR-based payloads for submission +to Veraison using a RESTful API. Hence, we will have to create a CoMID for the +reference value and a CoTS for the trust anchor. + +The command line tool, `cocli`, uses so-called templates as input to generate +the CBOR files. For completeness, the JSON files are shown below. + +The first command creates a CoMID based on two input files, one for trust +anchors and another one for reference values. The +`$VERAISON_SRC/end-to-end/input/src/comid-psa-ta.json` file contains +information about the trust anchor(s) and the +`$VERAISON_SRC/end-to-end/input/src/comid-psa-refval.json` file contains the +reference value(s). + +In our example, we need to provision the public key of the Attester to +Veraison. This allows Veraison to verify the digital signature covering the +Evidence (and the PSA attestation token in our case). + +The Evidence, which we will create later in this walkthrough, contains the +hashes of the bootloader (BL), the PSA Root of Trust (PRoT) and the Application +Root of Trust (ARoT). The details of these software components are explained in +https://datatracker.ietf.org/doc/draft-tschofenig-rats-psa-token/ The goal is +to provision the "reference" or "golden values" of these hashes to the +Verifier. This allows the Verifier to match the Evidence claims sent by the +Attester with the expected values. + +```sh +jq --arg a "$(cat $WORK_DIR/cert.pub)" \ + '.triples["attester-verification-keys"][0]["verification-keys"][0].value = $a' \ + $VERAISON_SRC/end-to-end/input/src/comid-psa-ta.json \ + > $WORK_DIR/comid-psa-ta.json + +cocli comid create \ + --template $WORK_DIR/comid-psa-ta.json \ + --template $VERAISON_SRC/end-to-end/input/src/comid-psa-refval.json \ + --output-dir $WORK_DIR +``` + +The public key, which we previously created, has to be copied into the +[`comid-psa-ta.json`](end-to-end/input/src/comid-psa-ta.json) file into the +`verification-keys` field. We do this using `jq` command above, but you can just +use your favorite text editor. The modified file is saved under +`$WORK_DIR/comid-pa-ta.json`. + +Search for the `BEGIN PUBLIC KEY` section in the JSON file below. The UEID +field contains information about the specific instance of the device and serves +as a key identifier. Hence, this instance ID has to match the Instance ID claim +in the Evidence. The Implementation ID claim uniquely identifies the +implementation of the immutable PSA RoT. Veraison uses this claim to locate the +details of the PSA RoT implementation. The Implementation ID is also found in +the Evidence claims. + +[comid-psa-ta.json](end-to-end/input/src/comid-psa-ta.json): + +```json { "lang": "en-GB", "tag-identity": { @@ -241,30 +340,40 @@ comid-psa-ta.json: "verification-keys": [ { "type": "pkix-base64-key", - "value": "-----BEGIN PUBLIC KEY-----\nMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEOq7AxYePubv1b3bhcszgwycyDKDBvIRL400LA4xoJWB5dU4DPiTbzFTjKXJCzO3oKitDv8RB260WMNhItGJQbg==\n-----END PUBLIC KEY-----" - + "value": "-----BEGIN PUBLIC KEY-----\nMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEOq7AxYePubv1b3bhcszgwycyDKDBvIRL400LA4xoJWB5dU4DPiTbzFTjKXJCzO3oKitDv8RB260WMNhItGJQbg==\n-----END PUBLIC KEY-----" } ] } ] } } -~~~ - -The reference values of the software contain the measurements with measurements for each component. The semantics of the reference values are described in https://datatracker.ietf.org/doc/html/draft-fdb-rats-psa-endorsements-03 (see Section 3.3), which is a measurement-map of a CoMID reference-triple-record. Because of the relationship to the software component contained in the Evidence -consult also Section 4.4.1 of https://datatracker.ietf.org/doc/draft-tschofenig-rats-psa-token/. - -Four fields are worth mentioning, namely - - - Label: The Label, which corresponds to the Measurement Type in the Evidence, is short string representing the role of this software component, such as "BL" or "PRoT". - - Version: The Version is the issued software version in the form of a text string. - - Signer-ID: The Signer ID is the hash of a signing authority public key for the software component. This can be used by a Verifier to ensure the components - were signed by an expected trusted source. - - digests: The Digests field, which corresponds to the Measurement Value in the Evidence, represents a hash of the invariant software component in memory at startup time. - -comid-psa-refval.json: - -~~~json +``` + +The reference values of the software contain the measurements for each +component. The semantics of the reference values are described in +https://datatracker.ietf.org/doc/html/draft-fdb-rats-psa-endorsements-03 (see +Section 3.3), which is a measurement-map of a CoMID reference-triple-record. +Because of the relationship to the software component contained in the Evidence +consult also Section 4.4.1 of +https://datatracker.ietf.org/doc/draft-tschofenig-rats-psa-token/. + +Four fields are worth mentioning, namely + + - Label: The Label, which corresponds to the Measurement Type in the Evidence, + is short string representing the role of this software component, such as + "BL" or "PRoT". + - Version: The Version is the issued software version in the form of a text + string. + - Signer-ID: The Signer ID is the hash of a signing authority public key for + the software component. This can be used by a Verifier to ensure the + components were signed by an expected trusted source. + - digests: The Digests field, which corresponds to the Measurement Value in + the Evidence, represents a hash of the invariant software component in + memory at startup time. + +[comid-psa-refval.json](end-to-end/input/src/comid-psa-refval.json): + +```json { "lang": "en-GB", "tag-identity": { @@ -295,95 +404,119 @@ comid-psa-refval.json: "model": "RoadRunner" } }, - "measurements": [ - { - "key": { - "type": "psa.refval-id", - "value": { - "label": "BL", - "version": "2.1.0", - "signer-id": "rLsRx+TaIXIFUjzkzhokWuGiOa48a/2eeHH35di66Gs=" - } - }, + "measurement": { + "key": { + "type": "psa.refval-id", "value": { - "digests": [ - "sha-256;h0KPxSKAPTEGXnvOPPA/5HUJZjHl4Hu9eg/eYMTPJcc=" - ] + "label": "BL", + "version": "2.1.0", + "signer-id": "rLsRx+TaIXIFUjzkzhokWuGiOa48a/2eeHH35di66Gs=" } }, - { - "key": { - "type": "psa.refval-id", - "value": { - "label": "PRoT", - "version": "1.3.5", - "signer-id": "rLsRx+TaIXIFUjzkzhokWuGiOa48a/2eeHH35di66Gs=" - } + "value": { + "digests": [ + "sha-256;h0KPxSKAPTEGXnvOPPA/5HUJZjHl4Hu9eg/eYMTPJcc=" + ] + } + } + }, + { + "environment": { + "class": { + "id": { + "type": "psa.impl-id", + "value": "YWNtZS1pbXBsZW1lbnRhdGlvbi1pZC0wMDAwMDAwMDE=" }, + "vendor": "ACME", + "model": "RoadRunner" + } + }, + "measurement": { + "key": { + "type": "psa.refval-id", "value": { - "digests": [ - "sha-256;AmOCmYm2/ZVPcrqvL8ZLwuLwHWktTecphuqAj26ZgT8=" - ] + "label": "PRoT", + "version": "1.3.5", + "signer-id": "rLsRx+TaIXIFUjzkzhokWuGiOa48a/2eeHH35di66Gs=" } }, - { - "key": { - "type": "psa.refval-id", - "value": { - "label": "ARoT", - "version": "0.1.4", - "signer-id": "rLsRx+TaIXIFUjzkzhokWuGiOa48a/2eeHH35di66Gs=" - } + "value": { + "digests": [ + "sha-256;AmOCmYm2/ZVPcrqvL8ZLwuLwHWktTecphuqAj26ZgT8=" + ] + } + } + }, + { + "environment": { + "class": { + "id": { + "type": "psa.impl-id", + "value": "YWNtZS1pbXBsZW1lbnRhdGlvbi1pZC0wMDAwMDAwMDE=" }, + "vendor": "ACME", + "model": "RoadRunner" + } + }, + "measurement": { + "key": { + "type": "psa.refval-id", "value": { - "digests": [ - "sha-256;o6XnFfDMV0pzw/m+u2vCTzL/1bZ7OHJEwskJ2neaFHg=" - ] + "label": "ARoT", + "version": "0.1.4", + "signer-id": "rLsRx+TaIXIFUjzkzhokWuGiOa48a/2eeHH35di66Gs=" } + }, + "value": { + "digests": [ + "sha-256;o6XnFfDMV0pzw/m+u2vCTzL/1bZ7OHJEwskJ2neaFHg=" + ] } - ] + } } ] } } -~~~ +``` -Next, we combine the two previously generated files (`comid-psa-refval.cbor` and `comid-psa-ta.cbor`) into a CoRIM using the following command: +Next, we combine the two previously generated files +(`$WORK_DIR/comid-psa-refval.cbor` and `$WORK_DIR/comid-psa-ta.cbor`) into a +CoRIM using the following command: -~~~bash -cocli corim create --template corim-psa.json \ - --comid tmp/comid-psa-refval.cbor \ - --comid tmp/comid-psa-ta.cbor \ - --output tmp/psa-corim.cbor -~~~ +```sh +cocli corim create \ + --template $VERASON_SRC/end-to-end/input/src/corim-psa.json \ + --comid $WORK_DIR/comid-psa-refval.cbor \ + --comid $WORK_DIR/comid-psa-ta.cbor \ + --output $WORK_DIR/psa-corim.cbor +``` -The content of the `corim-psa.json` file is shown below. It indicates the attestation Evidence profile being used and other meta-data. +The content of the [`corim-psa.json`](end-to-end/input/src/corim-psa.json) file is +shown below. It indicates the attestation Evidence profile being used and other +meta-data. -~~~json +```json { "corim-id": "5c57e8f4-46cd-421b-91c9-08cf93e13cfc", - "profiles": [ - "http://arm.com/psa/iot/1" - ], + "profile": "http://arm.com/psa/iot/1", "validity": { "not-before": "2021-12-31T00:00:00Z", "not-after": "2025-12-31T00:00:00Z" } } -~~~ +``` The CoRIM file can be submitted to Veraison using the following command: -~~~bash -cocli corim submit \ - --corim-file=tmp/psa-corim.cbor \ - --api-server=http://provisioning-service:8888/endorsement-provisioning/v1/submit \ - --media-type='application/corim-unsigned+cbor; profile="http://arm.com/psa/iot/1"' -~~~ +```sh + --corim-file $WORK_DIR/psa-corim.cbor \ + --media-type 'application/corim-unsigned+cbor; profile="http://arm.com/psa/iot/1"' +``` -By dumping the Veraison database with the "veraison stores" command we can see the correctly entered entries: +By dumping the Veraison database with the `veraison stores` command we can see +the correctly entered entries: -~~~json +```json TRUST ANCHORS: -------------- { @@ -446,39 +579,46 @@ ENDORSEMENTS: "PSA_IOT.version": "0.1.4" } } -~~~ +``` ## Manually Creating Attestation Evidence -We use the `evcli` tool to create attestation Evidence. Note that only two attestation formats are currently supported, namely the Arm PSA Token and Arm CCA. The repository can be found here: https://github.com/veraison/evcli/tree/main. In a more realistic setup, we would be using either software that emulates an Attester or, even better, a device that supports this functionality (like an Arm v8-M development board). - -To install the code, run - -~~~bash -go install github.com/veraison/evcli/v2@latest -~~~ +We use the `evcli` tool to create attestation Evidence. Note that only two +attestation formats are currently supported, namely the Arm PSA Token and Arm +CCA. The repository can be found here: https://github.com/veraison/evcli. In a +more realistic setup, we would be using either software that emulates an +Attester or, even better, a device that supports this functionality (like an +Arm v8-M development board). -Also, clone the repository to re-use the examples: - -~~~bash -git clone https://github.com/veraison/evcli.git -~~~ +The `evcli` tool is part of Veraison deployment, and, provided you've sourced +`env.bash`/`env.zsh`, should be aliased in your shell with appropriate +configuration. Note that we will re-use the previously created JWT in this example. -The `evcli` repository contains documentation for the use of the PSA attestation token format, which can be found at https://github.com/veraison/evcli/blob/main/README-PSA.md +The `evcli` tool's source repository contains documentation for the use of the +PSA attestation token format, which can be found at +https://github.com/veraison/evcli/blob/main/README-PSA.md -Two inputs are necessary to create the PSA attestation token, namely +Two inputs are necessary to create the PSA attestation token, namely -* A set of claims, and -* A private key to sign the token. +- A set of claims, and +- A private key to sign the token. -We are using the following claims, in JSON format, and encoding them into a file `psa-evidence.json`. Note that the combination of the `psa-instance-id` and the `psa-implementation-id` is used to identify the key. The `signer-id` contains the hash of the public key used to sign the software/firmware. These concepts are described in https://datatracker.ietf.org/doc/draft-tschofenig-rats-psa-token/ +We are using the following claims, in JSON format, encoded in the file +[`$VERASON_SRC/end-to-end/input/src/psa-evidence.json`](end-to-end/input/src/psa-evidence.json). +Note that the combination of the `psa-instance-id` and the +`psa-implementation-id` is used to identify the key. The `signer-id` contains +the hash of the public key used to sign the software/firmware. These concepts +are described in +https://datatracker.ietf.org/doc/draft-tschofenig-rats-psa-token/ -Note that the content of the evidence needs to correspond to the endorsements. Omitting claims or software components will cause verification failures. +Note that the content of the evidence needs to correspond to the endorsements. +Omitting claims or software components will cause verification failures. -~~~json +[`psa-evidence.json`](end-to-end/input/src/psa-evidence.json): +```json { "eat-profile": "http://arm.com/psa/2.0.0", "psa-client-id": 1, @@ -510,108 +650,113 @@ Note that the content of the evidence needs to correspond to the endorsements. O "psa-verification-service-indicator": "https://psa-verifier.org", "psa-nonce": "QUp8F0FBs9DpodKK8xUg8NQimf6sQAfe2J1ormzZLxk=" } -~~~ +``` -To create a PSA attestation token from the supplied claims and an attestation key in JSON Web Key (JWK) format we use the following command. Follow the instructions in the previous sub-section to create the attestation key. +To create a PSA attestation token from the supplied claims and an attestation +key in JSON Web Key (JWK) format we use the following command. Follow the +instructions in the previous sub-section to create the attestation key. -~~~bash +```sh evcli psa create \ - --claims=psa-evidence.json \ - --key=jwk.json \ - --token=my-token.cbor -~~~ + --claims $VERAISON_SRC/end-to-end/input/src/psa-evidence.json \ + --key $WORK_DIR/jwk.json \ + --token $WORK_DIR/my-token.cbor +``` -The specification of the PSA attestation token can be found at https://datatracker.ietf.org/doc/html/draft-tschofenig-rats-psa-token, which contains an explanation of the various claims and their semantics. +The specification of the PSA attestation token can be found at +https://datatracker.ietf.org/doc/html/draft-tschofenig-rats-psa-token, which +contains an explanation of the various claims and their semantics. -The command above will produce the PSA attestation token in CBOR format and protect it using COSE_Sign1. The result is stored in `my-token.cbor`. +The command above will produce the PSA attestation token in CBOR format and +protect it using COSE_Sign1. The result is stored in `my-token.cbor`. -To verify the Evidence locally, the token and the public key need to be provided to the following command: +To verify the Evidence locally, the token and the public key need to be +provided to the following command: -~~~bash -evcli psa check --token=my-token.cbor --key=pub.json -~~~ +```sh +evcli psa check --token $WORK_DIR/my-token.cbor --key $WORK_DIR/pub.json +``` If successful, it will return the list of claims: -~~~ +``` >> "my-token.cbor" verified >> embedded claims: {"eat-profile":http://arm.com/psa/2.0.0,"psa-client-id":1,"psa-security-lifecycle":12288,"psa-implementation-id":"UFFSU1RVVldQUVJTVFVWV1BRUlNUVVZXUFFSU1RVVlc=","psa-boot-seed":"3q2+796tvu/erb7v3q2+796tvu/erb7v3q2+796tvu8=","psa-software-components":[{"measurement-type":"BL","measurement-value":"AAECBAABAgQAAQIEAAECBAABAgQAAQIEAAECBAABAgQ=","signer-id":"UZIA/1GSAP9RkgD/UZIA/1GSAP9RkgD/UZIA/1GSAP8="},{"measurement-type":"PRoT","measurement-value":"BQYHCAUGBwgFBgcIBQYHCAUGBwgFBgcIBQYHCAUGBwg=","signer-id":"UZIA/1GSAP9RkgD/UZIA/1GSAP9RkgD/UZIA/1GSAP8="}],"psa-nonce":"QUp8F0FBs9DpodKK8xUg8NQimf6sQAfe2J1ormzZLxk=","psa-instance-id":"AaChoqOgoaKjoKGio6ChoqOgoaKjoKGio6ChoqOgoaKj","psa-verification-service-indicator":https://psa-verifier.org} -~~~ +``` -The `psa check` subcommand verifies the digital signature over the supplied PSA attestation token and checks whether its claim set is well-formed. +The `psa check` subcommand verifies the digital signature over the supplied PSA +attestation token and checks whether its claim set is well-formed. To test it against the Verifier, the `psa verify-as` subcommand is used. -It has two modes, namely one where the tool acts as an Attester and another mode where it acts as a Relying Party. The Relying Party mode uses the previously generated PSA token as input while the Attester mode creates the PSA attestation token on-the-fly. +It has two modes, namely one where the tool acts as an Attester and another +mode where it acts as a Relying Party. The Relying Party mode uses the +previously generated PSA token as input while the Attester mode creates the PSA +attestation token on-the-fly. Below, we use the Relying Party mode: -~~~bash -evcli psa verify-as relying-party \ - --api-server=http://verification-service:8080/challenge-response/v1/newSession \ - --token=my-token.cbor -~~~ +```sh +evcli psa verify-as relying-party --token $WORK_DIR/my-token.cbor | \ + tail -n 1 | tr -d \" > $WORK_DIR/ar.jwt +``` -The response will be an Attestation Result encoded as a JWT, which is signed with a JSON Web Signature (JWS). +The response will be an Attestation Result encoded as a JWT, which is signed +with a JSON Web Signature (JWS). -For example, the following JWT is an example response returned by the Verifier. It is a string consisting of three values separated by '.'. The first part is the header containing the signing algorithm and other information. The second part is the signed payload, and the last part is the digital signature itself. +For example, the following JWT is an example response returned by the Verifier. +It is a string consisting of three values separated by '.'. The first part is +the header containing the signing algorithm and other information. The second +part is the signed payload, and the last part is the digital signature itself. -~~~ +``` eyJhbGciOiJFUzI1NiIsInR5cCI6IkpXVCJ9.eyJlYXIudmVyaWZpZXItaWQiOnsiYnVpbGQiOiJOL0EiLCJkZXZlbG9wZXIiOiJWZXJhaXNvbiBQcm9qZWN0In0sImVhdF9ub25jZSI6IkZlaUJMMFlzMHl2WGlCYkFGTXMxT0hEWFh0dzA4UkdxX1NFU0pkU2FYUHNLazJBOF9BcnVMNDVaOFFxdWtUOG8iLCJlYXRfcHJvZmlsZSI6InRhZzpnaXRodWIuY29tLDIwMjM6dmVyYWlzb24vZWFyIiwiaWF0IjoxNzA2MDIzOTc5LCJzdWJtb2RzIjp7IlBTQV9JT1QiOnsiZWFyLmFwcHJhaXNhbC1wb2xpY3ktaWQiOiJwb2xpY3k6UFNBX0lPVCIsImVhci5zdGF0dXMiOiJhZmZpcm1pbmciLCJlYXIudHJ1c3R3b3J0aGluZXNzLXZlY3RvciI6eyJjb25maWd1cmF0aW9uIjowLCJleGVjdXRhYmxlcyI6MiwiZmlsZS1zeXN0ZW0iOjAsImhhcmR3YXJlIjoyLCJpbnN0YW5jZS1pZGVudGl0eSI6MiwicnVudGltZS1vcGFxdWUiOjIsInNvdXJjZWQtZGF0YSI6MCwic3RvcmFnZS1vcGFxdWUiOjJ9LCJlYXIudmVyYWlzb24uYW5ub3RhdGVkLWV2aWRlbmNlIjp7ImVhdC1wcm9maWxlIjoiaHR0cDovL2FybS5jb20vcHNhLzIuMC4wIiwicHNhLWJvb3Qtc2VlZCI6IjNxMis3OTZ0dnUvZXJiN3YzcTIrNzk2dHZ1L2VyYjd2M3EyKzc5NnR2dTg9IiwicHNhLWNsaWVudC1pZCI6MSwicHNhLWltcGxlbWVudGF0aW9uLWlkIjoiWVdOdFpTMXBiWEJzWlcxbGJuUmhkR2x2YmkxcFpDMHdNREF3TURBd01ERT0iLCJwc2EtaW5zdGFuY2UtaWQiOiJBYzdycm51Sko2TWlmbE1EejE0UEgzczB1MVFxMXlVS3dEKzgzamJzTHhVSSIsInBzYS1ub25jZSI6IkZlaUJMMFlzMHl2WGlCYkFGTXMxT0hEWFh0dzA4UkdxL1NFU0pkU2FYUHNLazJBOC9BcnVMNDVaOFFxdWtUOG8iLCJwc2Etc2VjdXJpdHktbGlmZWN5Y2xlIjoxMjI4OCwicHNhLXNvZnR3YXJlLWNvbXBvbmVudHMiOlt7Im1lYXN1cmVtZW50LXR5cGUiOiJCTCIsIm1lYXN1cmVtZW50LXZhbHVlIjoiaDBLUHhTS0FQVEVHWG52T1BQQS81SFVKWmpIbDRIdTllZy9lWU1UUEpjYz0iLCJzaWduZXItaWQiOiJyTHNSeCtUYUlYSUZVanpremhva1d1R2lPYTQ4YS8yZWVISDM1ZGk2NkdzPSIsInZlcnNpb24iOiIyLjEuMCJ9LHsibWVhc3VyZW1lbnQtdHlwZSI6IlBSb1QiLCJtZWFzdXJlbWVudC12YWx1ZSI6IkFtT0NtWW0yL1pWUGNycXZMOFpMd3VMd0hXa3RUZWNwaHVxQWoyNlpnVDg9Iiwic2lnbmVyLWlkIjoickxzUngrVGFJWElGVWp6a3pob2tXdUdpT2E0OGEvMmVlSEgzNWRpNjZHcz0iLCJ2ZXJzaW9uIjoiMS4zLjUifSx7Im1lYXN1cmVtZW50LXR5cGUiOiJBUm9UIiwibWVhc3VyZW1lbnQtdmFsdWUiOiJvNlhuRmZETVYwcHp3L20rdTJ2Q1R6TC8xYlo3T0hKRXdza0oybmVhRkhnPSIsInNpZ25lci1pZCI6InJMc1J4K1RhSVhJRlVqemt6aG9rV3VHaU9hNDhhLzJlZUhIMzVkaTY2R3M9IiwidmVyc2lvbiI6IjAuMS40In1dLCJwc2EtdmVyaWZpY2F0aW9uLXNlcnZpY2UtaW5kaWNhdG9yIjoiaHR0cHM6Ly9wc2EtdmVyaWZpZXIub3JnIn19fX0.r85Kv2iRZvQ2mIn70YKKfYF4apv7lhXdoiqao0Z6UlltXifDig9mPDLMvI4JKXKhlumzRZN3kCR54pcJBuCasw -~~~ +``` -The attestation result can be processed by a dedicated command line tool called 'arc'. The benefit of 'arc' is the proper decoding of the result. The documentation of the 'arc' tool can be found at https://github.com/veraison/ear/tree/main/arc +The attestation result can be processed by a dedicated command line tool called +'arc'. The benefit of 'arc' is the proper decoding of the result. The +documentation of the 'arc' tool can be found at +https://github.com/veraison/ear/tree/main/arc First, install the tool with the following command: -~~~bash +```sh go install github.com/veraison/ear/arc@latest -~~~ +``` -To obtain the public key for verifying the attestation result fetch it from .well-known using the following command: +To obtain the public key for verifying the attestation result fetch it from +.well-known using the following command: -~~~curl -wget http://localhost:8080/.well-known/veraison/verification -~~~ +```sh +wget --no-check-certificate -O- \ + https://localhost:8080/.well-known/veraison/verification | \ + jq '.["ear-verification-key"]' > $WORK_DIR/verif-pub.json +``` The result may be something like this: -~~~json +```json { - "ear-verification-key": { "alg": "ES256", "crv": "P-256", "kty": "EC", "x": "usWxHK2PmfnHKwXPS54m0kTcGJ90UiglWiGahtagnv8", "y": "IBOL-C3BttVivg-lSreASjpkttcsz-1rb7btKLv8EX4" - }, - "media-types": [ - "application/eat-collection; profile=\"http://arm.com/CCA-SSD/1.0.0\"", - "application/eat-cwt; profile=\"http://arm.com/psa/2.0.0\"", - "application/pem-certificate-chain", - "application/vnd.enacttrust.tpm-evidence", - "application/vnd.parallaxsecond.key-attestation.cca", - "application/vnd.parallaxsecond.key-attestation.tpm", - "application/psa-attestation-token" - ], - "version": "commit-b50b67d", - "service-state": "READY", - "api-endpoints": { - "newChallengeResponseSession": "/challenge-response/v1/newSession" - } } -~~~ +``` -Store the public key from the structure above in a separate file and verify the attestation result using `arc` using the following command. We assume that the attestation result is stored in `ar.txt`. +Store the public key from the structure above in a separate file and verify the +attestation result using `arc` using the following command. We assume that the +attestation result is stored in `ar.txt`. -~~~bash -arc verify --pkey=public_key.json --verbose --alg=ES256 ar.txt -~~~ +```sh +arc verify --pkey $WORK_DIR/verif-pub.json --verbose --alg ES256 $WORK_DIR/ar.jwt +``` The result is then shown as follows: -~~~ +``` >> "ar.txt" signature successfully verified using "public_key.json" [claims-set] { @@ -679,22 +824,25 @@ Hardware [affirming]: An Attester has passed its hardware and/or firmware verifi Runtime Opaque [affirming]: the Attester's executing Target Environment and Attesting Environments are encrypted and within Trusted Execution Environment(s) opaque to the operating system, virtual machine manager, and peer applications. Storage Opaque [affirming]: the Attester encrypts all secrets in persistent storage via using keys which are never visible outside an HSM or the Trusted Execution Environment hardware. Sourced Data [none]: The Evidence received is insufficient to make a conclusion. -~~~ +``` -Alternatively, it is also possible to display the attestation result using an online tool, for example, https://jwt.io. There are also many command line tools available to parse JWTs. +Alternatively, it is also possible to display the attestation result using an +online tool, for example, https://jwt.io. There are also many command line +tools available to parse JWTs. -Once parsed, the header shows the digital signature algorithm that was used to protect the claims of the JWT +Once parsed, the header shows the digital signature algorithm that was used to +protect the claims of the JWT -~~~json +```json { "alg": "ES256", "typ": "JWT" } -~~~ +``` The header is followed by this payload: -~~~json +```json { "ear.verifier-id": { "build": "N/A", @@ -750,19 +898,29 @@ The header is followed by this payload: } } } -~~~ +``` -The claims contained in this Attestation Result are described in https://datatracker.ietf.org/doc/draft-fv-rats-ear/. The trustworthiness vector shows the processing of the evaluation result. The overall appraisal status for the attester is found in the `ear.status` field. The values for these claims are re-used from another specification, namely from AR4SI (see https://datatracker.ietf.org/doc/draft-ietf-rats-ar4si/). +The claims contained in this Attestation Result are described in +https://datatracker.ietf.org/doc/draft-fv-rats-ear/. The trustworthiness vector +shows the processing of the evaluation result. The overall appraisal status for +the attester is found in the `ear.status` field. The values for these claims +are re-used from another specification, namely from AR4SI (see +https://datatracker.ietf.org/doc/draft-ietf-rats-ar4si/). -To use the Attester mode, use the following command assuming the private key is available in JWK format and has been copied into the same directory where the two input files are located. +To use the Attester mode, use the following command assuming the private key is +available in JWK format and has been copied into the same directory where the +two input files are located. -~~~bash +```sh evcli psa verify-as attester \ - --api-server=http://verification-service:8080/challenge-response/v1/newSession \ - --claims=psa-evidence-without-nonce.json \ - --key=jwk.json -~~~ + --claims $VERAISON_SRC/end-to-end/input/psa-claims-profile-2-without-nonce.json \ + --key $WORK_DIR/jwk.json +``` -The content of `psa-evidence-without-nonce.json` corresponds to the content of the previously used file `psa-evidence.json` but with the nonce claim omitted. +The content of +`$VERASON_SRC/end-to-end/input/psa-claims-profile-2-without-nonce-without-nonce.json` +corresponds to the content of the previously used file +`$VERASON_SRC/end-to-end/input/src/psa-evidence.json` but with the nonce claim +omitted. -If successful, this protocol interaction will produce an attestation result as a JWT. +If successful, this protocol interaction will produce an attestation result as a JWT.