From ecbf84998a0775dea56f4a236ab80a000967a04e Mon Sep 17 00:00:00 2001 From: Simon Ott Date: Wed, 21 Feb 2024 20:12:38 +0000 Subject: [PATCH] doc: Updated documentation Signed-off-by: Simon Ott --- README.md | 101 +++++++++++-------------- doc/Architecture.md | 18 +++-- doc/integration.md | 107 ++++++++++++++++++++++++++ doc/manual-setup.md | 179 +++++++++++++++++++++++++++++++------------- 4 files changed, 287 insertions(+), 118 deletions(-) create mode 100644 doc/integration.md diff --git a/README.md b/README.md index 6b64622f..ff2fd29d 100644 --- a/README.md +++ b/README.md @@ -5,10 +5,10 @@ [![Go Report Card](https://goreportcard.com/badge/github.com/Fraunhofer-AISEC/cmc)](https://goreportcard.com/report/github.com/Fraunhofer-AISEC/cmc) The CMC repository provides tools and software to enable remote attestation of computing platforms, -as well as remote attested TLS channels between those platforms. Currently, the CMC repository -supports Trusted Platform Module (TPM) attestation, as well as AMD SEV-SNP attestation. The goal -is to make attestation easy for verifiers without prior knowledge of the software stack, based -on a set of trusted CAs and signed metadata describing the software stack. +as well as remote attested TLS and HTTPS channels between those platforms. Currently, the CMC +repository supports Trusted Platform Module (TPM) attestation, as well as AMD SEV-SNP attestation. +The goal is to make attestation easy for verifiers without prior knowledge of the software stack, +based on a set of trusted CAs and signed metadata describing the software stack. *A detailed description of the architecture can be found in our* *[paper](https://dl.acm.org/doi/pdf/10.1145/3600160.3600171) and in the* @@ -21,13 +21,15 @@ on a set of trusted CAs and signed metadata describing the software stack. - For AMD SEV-SNP an SNP-capable AMD server - Building the *cmcd* requires *go* (https://golang.org/doc/install) -## Quick Demo Setup +## Quick Start -The CMC repository contains a complete local example setup including a demo CA and all required -configurations and metadata. It was tested on Ubuntu 22.04 LTS. +The CMC repository contains a complete local TPM-based example setup including a demo CA and all +required configurations and metadata. It was tested on Ubuntu 22.04 LTS. > :warning: **Note:** You should run this only for testing on a development machine, or inside -> a Virtual Machine (VM). The software directly interacts with the hardware (TPM or AMD SP). +> a Virtual Machine (VM). The software directly interacts with the TPM + +### Setup and Build Clone the repository: ```sh @@ -45,15 +47,11 @@ For the JSON example configuration folders to work without modifications, choose the folder `cmc-data` located in the same root folder the `cmc` repository resides in. Export this root folder as `$CMC_ROOT`. -*For an alternative demo setup with a more complex PKI and policies based on the requirements of* -*the International Data Spaces (IDS), see [IDS Example Setup](./doc/ids-example-setup.md)* - -*For instructions on creating and signing the metadata with an arbitrary PKI yourself,* -*see [Manual Setup](./doc/manual-setup.md)* +### Run -## Run - -### Generate and Verify Attestation Reports +The tools can generate and verify attestation reports, establish attested TLS connections and +establish attested HTTPS connections. For detailed instructions refer to +[Manual Setup](./doc/manual-setup.md) ```sh # Start the EST server that supplies the certificates and metadata for the cmcd @@ -62,63 +60,48 @@ Export this root folder as `$CMC_ROOT`. # Build and run the cmcd ./cmcd -config $CMC_ROOT/cmc-data/cmcd-conf.json -# Run the testtool to retrieve an attestation report (stored in current folder unless otherwise specified) -./testtool -mode generate - -# Run the testtool to verify the attestation report (stored in current folder unless otherwise specified) -./testtool -mode verify -ca $CMC_ROOT/cmc-data/pki/ca.pem -``` - -Note that the JSON configuration files in the example setup contain relative paths and the -above commands are meant to be run from within the respective source directories inside the -`cmc` repository. - -### Establish Attested TLS Connections - -Instead of using the `testtool` to simply generate and verify attestation reports, it can also -be used to establish attested TLS connections: - -```sh # Run an attested TLS server -./testtool -mode listen -addr 0.0.0.0:4443 -ca $CMC_ROOT/cmc-data/pki/ca.pem -mtls +./testtool -config $CMC_ROOT/cmc-data/testtool-conf.json -mode listen # Run an attested TLS client estblishing a mutually attested TLS connection to the server -./testtool -mode dial -addr localhost:4443 -ca $CMC_ROOT/cmc-data/pki/ca.pem -mtls -``` - -### Establish Attested HTTPS Connection - -The `testtool` can also perform user-specified attested HTTPS requests and act as an attested HTTPS demo server, respectively. - -```sh -# Run two attested HTTPS servers -./testtool -config $CMC_ROOT/testtool-config.json -addr 0.0.0.0:8081 -mode serve -./testtool -config $CMC_ROOT/testtool-config.json -addr 0.0.0.0:8082 -mode serve - -# Perform multiple user-specified attested HTTPS requests to both servers. Each connection is attested, while multiple requests to the same server use the established attested TLS connections -./testtool \ - -config ../../cmc-data/testtool-lib-config.json \ - -addr https://localhost:8081/post,https://localhost:8082/post \ - -mode request \ - -method POST \ - -data "hello from attested HTTPS client" \ - -header "Content-Type: text/plain" +./testtool -config $CMC_ROOT/cmc-data/testtool-conf.json -mode dial ``` - **Note**: The *cmcd* TPM provisioning process includes the verification of the TPM's EK certificate chain. In the example setup, this verification is turned off, as the database might not contain the certificate chain for the TPM of the machine the *cmcd* is running on. Instead, simply a warning is printed. The intermediate and root CA for this chain can be downloaded from the TPM -vendor. The certificates can then be added in to the ```cmc/example-setup/tpm-ek-certs.db``` -database. The ```verifyEkCert``` parameter in the *estserver* config can then be set to true. +vendor. The certificates can then be added in to the `cmc/example-setup/tpm-ek-certs.db` +database. The `verifyEkCert` parameter in the *estserver* config can then be set to true. + +## Further Documentation -## Configuration +### Architecture + +An overview of the architecture is given in [Architecture](./doc/Architecture.md). + +### Configuration The tools can be configured via JSON configuration files and commandline flags. For an explanation, each binary can be run with the `-help` flag. All configuration options are explained in the [Configuration Documentation](./doc/configuration.md). -## Build +#### Detailed Setup + +For instructions on creating and signing the metadata with an arbitrary PKI yourself, +see [Manual Setup](./doc/manual-setup.md) + +### Build See [Build Documentation](./doc/build.md) + +### Integration + +Usually, the attested TLS or HTTPS libraries are used within own projects to provide attestation +for TLS or HTTPS connections, as described in [Integration](./doc/integration.md) + +### Additional Demo Setups + +For an alternative demo setup with a more complex PKI and policies based on the requirements of +the International Data Spaces (IDS), see [IDS Example Setup](./doc/ids-example-setup.md) + diff --git a/doc/Architecture.md b/doc/Architecture.md index a00c47eb..65355290 100644 --- a/doc/Architecture.md +++ b/doc/Architecture.md @@ -80,10 +80,18 @@ __attestedtls:__ The *attestedtls* package provides an exemplary protocol which shows how a connection between two parties can be performed using remote attestation. After a tls connection is established, additional steps are performed to obtain and verify the attestation reports from the respective communication -partner. Only then is the connection provided to the server / client. +partner. Only then is the connection provided to the server / client. For an example on how to +integrate the library into own applications, the *testtool* with its modes *listen* and +*dial* can serve as an exemplary application. + +__attestedhttp:__ +The *attestedhttp packages utilizes **attestedtls** to provide HTTPS client and server capabilities +to applications. For an example on how to integrate the library into own applications, the +*testtool* with its modes *listen* and *dial* can serve as an exemplary application. __testtool:__ -The *testtool* can generate and verify attestation reports and establish attested TLS connections. -To estblish attestation TLS connections, the testtool makes use of the attested TLS package and thus -services provided by the cmcd to create an attested TLS connection. The client can be configured to -use one-sided or mutual attestation. +The *testtool* can generate and verify attestation reports and establish attested TLS as well as +attested HTTPS connections. For the latter, it makes use of the *attestedtls* and +*attestedhttp* packages. The testtool can act as a standalone application, i.e., integrate +all *cmc* functionality via their go API, or as a tool that interacts with the +*cmcd* via a gRPC, CoAP or socket API for performing remote attestation. diff --git a/doc/integration.md b/doc/integration.md new file mode 100644 index 00000000..372cbb8f --- /dev/null +++ b/doc/integration.md @@ -0,0 +1,107 @@ +# Integration + +To integrate attestation into own projects, run the *cmcd* on your system and replace the +go standard library `crypto/tls` or `net/http` package with the `cmc/attestedtls` or +`cmc/attestedhttp` package respectively. The API was kept as close as possible to the +original API, so that only some additional config options must be provided and many +data types, such as `net.Conn` (https://pkg.go.dev/net#Conn) can still be used. + +In the following examples, error handling was omitted for simplicity. For the configurations, +see [configuration](./configuration.md) or look at the *testtool* code. + +## Attested TLS + +### Client + +```go +// Import the attested TLS package +import atls "github.com/Fraunhofer-AISEC/cmc/attestedtls" + +// Create CMC configuration (see configuration documentation) +conf := &CmcConfig{ + // ... +} + +// Establish attested TLS client connection +conn, _ := atls.Dial("tcp", "localhost:4443", tlsConf, atls.WithCmcConfig(conf)) +defer conn.Close() + +// Send data over the attested TLS connection +_, _ = conn.Write([]byte("Hello, World")) +``` + +### Server + +```go +// Import the attested TLS package +import atls "github.com/Fraunhofer-AISEC/cmc/attestedtls" + +// Create server TLS configuration +tlsConf := &tls.Config{ + Certificates: []tls.Certificate{cert}, + ClientAuth: clientAuth, + ClientCAs: roots, +} + +// Create CMC configuration (see configuration documentation) +conf := &CmcConfig{ + // ... +} + +// Create an attested TLS listener +ln, _ := atls.Listen("tcp", "localhost:4443", tlsConf, atls.WithCmcConfig(conf)) +defer ln.Close() + +for { + // Accept connection and perform remote attestation + conn, _ := ln.Accept() + + // Handle established connections + go handle(conn) +} +``` + +## Attested HTTP + +### Client + +```go +// Import the attested HTTPS package +import ahttp "github.com/Fraunhofer-AISEC/cmc/attestedhttp" + +// Create attested HTTPS transport +transport := &ahttp.Transport{ + IdleConnTimeout: 60 * time.Second, + TLSClientConfig: tlsConfig, + // Additional CMC configuration (see configuration documentation) +} + +// Create attested HTTP client +client := &ahttp.Client{Transport: transport} + +// Perform attested HTTPS GET request +resp, _ := client.Do("https://localhost:80/hello") +``` + +### Server + +```go +// Import the attested HTTPS package +import ahttp "github.com/Fraunhofer-AISEC/cmc/attestedhttp" + +// Create attested HTTP server +server := &ahttp.Server{ + Server: &http.Server{ + Addr: addr, + TLSConfig: tlsConfig, + }, + // Additional CMC configuration (see configuration documentation) +} + +// Use the golang net/http module functions to configure the server as usual +http.HandleFunc("/hello", handleRequest) + +// Call the attested ListenAndServe method from the attested HTTP server +// to run the server +_ = server.ListenAndServe() +``` \ No newline at end of file diff --git a/doc/manual-setup.md b/doc/manual-setup.md index 9d64016d..fd8c72e4 100644 --- a/doc/manual-setup.md +++ b/doc/manual-setup.md @@ -56,21 +56,101 @@ $CMC_ROOT/cmc-data/setup-simple-pki -i $CMC_ROOT/cmc-data -o $CMC_ROOT/cmc-data/ ### 3. Generate metadata -This example uses a TPM as hardware trust anchor and an SRTM measured boot. For other setups, -see [Generating Metadata and Setup Alternatives](#generating-metadata-and-setup-alternatives) +The example setup (folder `cmc/example-setup`) contains templates for the required metadata files +in JSON. The attributes of these files can be adjusted according to individual requirements: + +- **rtm.manifest.json**: Contains information about the Root of Trust for Measurements, which +usually comprises the reference values (hashes) for BIOS/UEFI, bootloader and other early boot +components +- **os.manifest.json**: Contains the operating system reference values and information +- **app.manifest.json**: Contains the reference values for an app on the system +- **company.description.json**: Optional, metadata describing the operater of the computing platform +- **device.description.json**: Metadata describing the overall platform, contains links to +RTM Manifest, OS Manifest and App Manifests +- **device.config.json**: Signed local device configuration, contains e.g. the parameters for +the Certificate Signing Requests for the attestation and identity keys + +### Serialization Format + +The attestation report can be serialized to JSON and signed via JSON Web signatures (JWS), or to +CBOR and signed via CBOR Object Signing and Encryption (COSE). This must be specified in the +configuration of the *cmcd* (see [CMCD Configuration](#cmcd-configuration) and the +provisioning server (see [Provisioning Server Configuration](#provisioning-server-configuration)) + +As CBOR is a binary serialization format, the serialized data is not human-readable. Therefore, the +metadata templates are always in JSON. A converter tool is provided to convert the metadata files +to CBOR before signing them. To convert a metadata file from JSON to CBOR: ```sh -# Parse the values of the RTM PCRs from the kernel's binary bios measurements as reference values +# Convert JSON to CBOR using the converter-tool +$CMC_ROOT/cmc/tools/cmc-converter/cmc-converter -in .json -out -inform json -outform cbor +``` + +#### Reference Values + +The self-contained attestation reports (see [Architecture](./Architecture.md)) contain signed +reference-values that describe the legitimate software that is expected to be running on the +platform. The trust in the measurements comes from hardware-based measurement technologies, such +as TPMs or Confidential Computing technologies. The reference values for the proving platform must +be generated based on the used technology. + +##### TPM Reference Values + +The reference values can either be parsed once on a good reference platform in a secure environment, +or they can be calculated based on the built software artifacts of a computing platform (e.g., +within a build-system such as *Yocto* or *Buildroot*). Tools for parsing and calculated +are available as open source [tpm-pcr-tools](). + +**Parsing the reference values on a good reference platform and inserting them into the manifest** +```sh +# Parse the values of the RTM PCRs from the kernel's binary bios measurement log +ements as reference values referenceValues=$(sudo parse-srtm-pcrs -p 0,1,2,3,4,5,6,7 -f json) # Delete existing reference values in the RTM Manifest jq 'del(.referenceValues[])' $CMC_ROOT/cmc-data/metadata-raw/rtm.manifest.json | sponge $CMC_ROOT/cmc-data/metadata-raw/rtm.manifest.json +# Add new reference values to the RTM Manifest jq --argjson ver "$referenceValues" '.referenceValues += $ver' $CMC_ROOT/cmc-data/metadata-raw/rtm.manifest.json | sponge $CMC_ROOT/cmc-data/metadata-raw/rtm.manifest.json +# Parse the values of the OS PCRs from the kernel's binary bios measurement log referenceValues=$(sudo parse-srtm-pcrs -p 8,9 -f json) +# Delete existing reference values in the OS Manifest jq 'del(.referenceValues[])' $CMC_ROOT/cmc-data/metadata-raw/os.manifest.json | sponge $CMC_ROOT/cmc-data/metadata-raw/os.manifest.json +# Add new reference values to the OS Manifest jq --argjson ver "$referenceValues" '.referenceValues += $ver' $CMC_ROOT/cmc-data/metadata-raw/os.manifest.json | sponge $CMC_ROOT/cmc-data/metadata-raw/os.manifest.json ``` +**Calculating the reference values based on software artifacts** + +This currently only works for QEMU VMs with OVMF and a Linux kernel +```sh +# Calculate reference values for the RTM Manifest +referenceValues=$($(calculate-srtm-pcrs \ + --format json \ + --pcrs 0,1,2,3,6,7 \ + --eventlog \ + --kernel "linux-kernel.bzImage" \ + --ovmf "OVMF.fd" \ + --config "calculate-pcrs.cfg" \ + ) + +# Delete all existing reference values in the RTM manifest +jq 'del(.referenceValues[])' $CMC_ROOT/cmc-data/metadata-raw/rtm.manifest.json | sponge $CMC_ROOT/cmc-data/metadata-raw/rtm.manifest.json +# Insert new reference values to the RTM Manifest +jq --argjson ver "$referenceValues" '.referenceValues += $ver' $CMC_ROOT/cmc-data/metadata-raw/rtm.manifest.json | sponge $CMC_ROOT/cmc-data/metadata-raw/rtm.manifest.json +``` + +##### AMD SNP Reference Values + +tbd + +##### Intel TDX Reference Values + +tbd + +##### Intel SGX Reference Values + +tbs + ### 4. Sign the metadata This example uses JSON/JWS as serialization format. For different formats @@ -90,70 +170,61 @@ cmc-signing-tool -in $IN/device.description.json -out $OUT/device.description.j cmc-signing-tool -in $IN/device.config.json -out $OUT/device.config.json -keys $KEY -x5cs $CHAIN ``` -### 5. Adjust the *cmcd* configuration +### 5. Adjust the configuration files -Open the cmcd-configuration in `$CMC_ROOT/cmc-data/cmcd-conf.json` and adjust it if required. -For more information about the configuration see [CMCD Configuration](#cmcd-configuration) -or run `cmcd -help` +Adjust the configuration files for the tools as required according to +[Configuration](#cmcd-configuration). -### 6. Adjust the provisioning server configuration -Open the provisioning server configuration in `$CMC_ROOT/cmc-data/prov-server-conf.json` and -adjust it if required. For more information about the configuration see -[Provisioning Server Configuration](#provisioning-server-configuration) or run `provserver -help` +### 6. Run -## Generating Metadata and Setup Alternatives +#### Run the EST and Provisioning Server -Metadata and PKI can be generated in different serialization formats and configurations. +```sh +# Start the EST server that supplies the certificates and metadata for the cmcd +./estserver -config $CMC_ROOT/cmc-data/est-server-conf.json +``` -### Metadata +#### Run the cmcd -The example setup contains templates for the required metadata files in JSON. The attributes -of these files can be adjusted according to individual requirements: +```sh +# Build and run the cmcd +./cmcd -config $CMC_ROOT/cmc-data/cmcd-conf.json +``` -- **rtm.manifest.json**: Contains information about the Root of Trust for Measurements, which -usually comprises the reference values (hashes) for BIOS/UEFI, bootloader and other early boot -components -- **os.manifest.json**: Contains the operating system reference values and information -- **company.description.json**: Optional, metadata describing the operater of the computing platform -- **device.description.json**: Metadata describing the overall platform, contains links to -RTM Manifest, OS Manifest and App Manifests -- **device.config.json**: Signed local device configuration, contains e.g. the parameters for -the Certificate Signing Requests for the attestation and identity keys +#### Generate and Verify Attestation Reports -### Serialization Format +```sh +# Run the testtool to retrieve an attestation report (stored in current folder unless otherwise specified) +./testtool -mode generate -The attestation report can be serialized to JSON and signed via JSON Web signatures (JWS), or to -CBOR and signed via CBOR Object Signing and Encryption (COSE). This must be specified in the -configuration of the *cmcd* (see [CMCD Configuration](#cmcd-configuration) and the -provisioning server (see [Provisioning Server Configuration](#provisioning-server-configuration)) +# Run the testtool to verify the attestation report (stored in current folder unless otherwise specified) +./testtool -mode verify -ca $CMC_ROOT/cmc-data/pki/ca.pem +``` -As CBOR is a binary serialization format, the serialized data is not human-readable. Therefore, the -metadata templates are always in JSON. A converter tool is provided to convert the metadata files -to CBOR before signing them. To convert a metadata file from JSON to CBOR: +#### Establish Attested TLS Connections ```sh -# Convert JSON to CBOR using the converter-tool -$CMC_ROOT/cmc/tools/cmc-converter/cmc-converter -in .json -out -inform json -outform cbor -``` -### TPM Setup using Calculated Values +# Run an attested TLS server +./testtool -mode listen -addr 0.0.0.0:4443 -ca $CMC_ROOT/cmc-data/pki/ca.pem -mtls -In the example setup, the platform is simply seen as a "good reference platform" and the -reference values are generated through parsing the TPM measurements from the `sysfs`. Ideally, the -reference values are generated from the single software artefacts running on the platform. For -QEMU VMs with OVMF and a kernel with appended initramfs, the `calculate-srtm-pcrs` tool can -be used: +# Run an attested TLS client estblishing a mutually attested TLS connection to the server +./testtool -mode dial -addr localhost:4443 -ca $CMC_ROOT/cmc-data/pki/ca.pem -mtls +``` -```sh -# 5. a) TPM Setup using calculated values -# Calculate reference values -referenceValues=$(calculate-srtm-pcrs --kernel linux-amd64-virtio-systemd-debug.bzImage --ovmf OVMF-DEBUG.fd --format json --pcrs 0,1,2,3,6,7 --eventlog --config configs/ovmf-f80580f56b.cfg) -# Delete all existing reference values -jq 'del(.referenceValues[])' $CMC_ROOT/cmc-data/metadata-raw/rtm.manifest.json | sponge $CMC_ROOT/cmc-data/metadata-raw/rtm.manifest.json -# Insert new reference values -jq --argjson ver "$referenceValues" '.referenceValues += $ver' $CMC_ROOT/cmc-data/metadata-raw/rtm.manifest.json | sponge $CMC_ROOT/cmc-data/metadata-raw/rtm.manifest.json +#### Establish Attested HTTPS Connections -referenceValues=$(calculate-srtm-pcrs --kernel linux-amd64-virtio-systemd-debug.bzImage --ovmf OVMF-DEBUG.fd --format json --pcrs 4,5 --eventlog --config configs/ovmf-f80580f56b.cfg) -jq 'del(.referenceValues[])' $CMC_ROOT/cmc-data/metadata-raw/os.manifest.json | sponge $CMC_ROOT/cmc-data/metadata-raw/os.manifest.json -jq --argjson ver "$referenceValues" '.referenceValues += $ver' $CMC_ROOT/cmc-data/metadata-raw/os.manifest.json | sponge $CMC_ROOT/cmc-data/metadata-raw/os.manifest.json -``` \ No newline at end of file +```sh +# Run two attested HTTPS servers +./testtool -config $CMC_ROOT/testtool-config.json -addr 0.0.0.0:8081 -mode serve + +# Perform multiple user-specified attested HTTPS requests to both servers. Each connection is +# attested, while multiple requests to the same server use the established attested TLS connections +./testtool \ + -config ../../cmc-data/testtool-lib-config.json \ + -addr https://localhost:8081/post,https://localhost:8082/post \ + -mode request \ + -method POST \ + -data "hello from attested HTTPS client" \ + -header "Content-Type: text/plain" +```