Compare commits

...

19 Commits

Author SHA1 Message Date
renovate[bot]
b99816cc66
deps: update alpine Docker tag to v3.17.2 (#1552)
Co-authored-by: Paul Meyer <49727155+katexochen@users.noreply.github.com>
2023-03-29 15:43:50 +02:00
renovate[bot]
f0fc655365
deps: update golang.org/x/vuln digest to 9550759 (#1550)
Co-authored-by: Paul Meyer <49727155+katexochen@users.noreply.github.com>
2023-03-29 15:43:24 +02:00
renovate[bot]
b12858660e
deps: update github.com/gophercloud/utils digest to 05e9e7f (#1549)
Co-authored-by: Paul Meyer <49727155+katexochen@users.noreply.github.com>
2023-03-29 15:42:34 +02:00
Daniel Weiße
eed533932e
rfc: attestation config options (#1436)
Signed-off-by: Daniel Weiße <dw@edgeless.systems>
Co-authored-by: Otto Bittner <cobittner@posteo.net>
2023-03-29 14:58:57 +02:00
renovate[bot]
96cdf108e4
deps: update golang:1.20.2 Docker digest to 2101aa9 (#1551)
Co-authored-by: Paul Meyer <49727155+katexochen@users.noreply.github.com>
2023-03-29 14:56:55 +02:00
renovate[bot]
c8625f4672
deps: update gcr.io/distroless/static:nonroot Docker digest to 149531e (#1548)
Co-authored-by: Paul Meyer <49727155+katexochen@users.noreply.github.com>
2023-03-29 14:56:29 +02:00
renovate[bot]
6013665de1
deps: update gcr.io/distroless/static Docker digest to 8d4cc4a (#1547)
Co-authored-by: Paul Meyer <49727155+katexochen@users.noreply.github.com>
2023-03-29 14:56:07 +02:00
miampf
c1dbf0561a
feat: added journald collection package to bootstrapper internal packages 2023-03-29 14:45:13 +02:00
Malte Poll
2a8169dd3b
ci: use bazel repository cache for tidy checks (#1525) 2023-03-29 14:13:51 +02:00
Daniel Weiße
fc0efb6309
config: deprecate confidentialVM option for Azure clusters in favor of using attestationVariant option (#1539)
* Remove confidentialVM option from azure provider config

* Fix cloudcmd creator test

---------

Signed-off-by: Daniel Weiße <dw@edgeless.systems>
2023-03-29 14:04:37 +02:00
Nils Hanke
1b832ac959
atls: fix link in README.md (#1545)
Co-authored-by: Daniel Weiße <66256922+daniel-weisse@users.noreply.github.com>
2023-03-29 13:33:19 +02:00
Thomas Tendyck
091fe3e2d7 measurements: compare to constants for clarity 2023-03-29 12:03:29 +02:00
renovate[bot]
83e6b4d64d
deps: update Constellation containers (#1504)
Co-authored-by: Paul Meyer <49727155+katexochen@users.noreply.github.com>
2023-03-29 11:31:26 +02:00
edgelessci
8f21e1d85c
deps: update apk package hashes (#1528)
Co-authored-by: Paul Meyer <49727155+katexochen@users.noreply.github.com>
2023-03-29 11:29:20 +02:00
Daniel Weiße
b57413cfa7
cli: set cluster's initial measurements from user's config using Helm (#1540)
* Remove using measurements from the initial control-plane node for the cluster's initial measurements

* Add using measurements from the user's config for the cluster's initial measurements to align behavior with upgrade command

---------

Signed-off-by: Daniel Weiße <dw@edgeless.systems>
2023-03-29 11:16:56 +02:00
Thomas Tendyck
6fabb2a84b docs: rearrange troubleshooting 2023-03-29 10:57:17 +02:00
Otto Bittner
7520d31467
docs: update govulncheck badge to new workflow (#1531)
govulncheck was integrated into the bazel check target
2023-03-29 10:26:45 +02:00
Daniel Weiße
99b12e4035
internal: refactor oid package to variant package (#1538)
Signed-off-by: Daniel Weiße <dw@edgeless.systems>
2023-03-29 09:30:13 +02:00
Daniel Weiße
db5660e3d6
attestation: add context to Issue and Validate methods (#1532)
Signed-off-by: Daniel Weiße <dw@edgeless.systems>
2023-03-29 09:06:10 +02:00
105 changed files with 875 additions and 561 deletions

View File

@ -1,4 +1,4 @@
FROM golang:1.20.2@sha256:bd4a3e7eee6d6ea30b2e27d6c1ac3c56809e78e08c7e44ddf91f8c741091f5ad as builder
FROM golang:1.20.2@sha256:2101aa981e68ab1e06e3d4ac35ae75ed122f0380e5331e3ae4ba7e811bf9d256 as builder
# Download project root dependencies
WORKDIR /workspace

View File

@ -26,6 +26,12 @@ jobs:
sudo apt-get update && sudo apt-get -y install libcryptsetup-dev libvirt-dev
echo "::endgroup::"
- name: Setup Bazel
uses: ./.github/actions/setup_bazel
with:
useCache: "true"
buildBuddyApiKey: ${{ secrets.BUILDBUDDY_ORG_API_KEY }}
- name: Setup Go environment
uses: actions/setup-go@6edd4406fa81c3da01a34fa6f6343087c207a568 # v3.5.0
with:

View File

@ -23,6 +23,7 @@ jobs:
- name: Build common targets
run: |
bazel build \
//bazel/ci/... \
//bootstrapper/cmd/bootstrapper:bootstrapper_linux_amd64 \
//cli:cli_oss_linux_amd64 \
//cli:cli_oss_darwin_amd64 \

View File

@ -4,7 +4,7 @@
<p>
<a href="https://github.com/edgelesssys/constellation/blob/main/LICENSE"><img src="https://img.shields.io/github/license/edgelesssys/constellation" alt="Constellation License"></a>
<a href="https://github.com/edgelesssys/constellation/actions/workflows/test-govulncheck.yml?query=branch%3Amain"><img src="https://github.com/edgelesssys/constellation/actions/workflows/test-govulncheck.yml/badge.svg?branch=main" alt="Govulncheck"></a>
<a href="https://github.com/edgelesssys/constellation/actions/workflows/test-tidy.yml/badge.svg?branch=main"><img src="https://github.com/edgelesssys/constellation/actions/workflows/test-tidy.yml/badge.svg?branch=main" alt="Govulncheck"></a>
<a href="https://goreportcard.com/report/github.com/edgelesssys/constellation/v2"><img src="https://goreportcard.com/badge/github.com/edgelesssys/constellation/v2" alt="Go Report"></a>
<a href="https://discord.gg/rH8QTH56JN"><img src="https://img.shields.io/discord/823900998606651454?color=7389D8&label=discord&logo=discord&logoColor=ffffff" alt="Discord"></a>
<a href="https://twitter.com/EdgelessSystems"><img src="https://img.shields.io/twitter/follow/EdgelessSystems?label=Follow" alt="Twitter"></a>

View File

@ -2,7 +2,6 @@
95f83a74e872b62360f6c6623a773e07a864e3313a127f57910caba368fed04b v3.17/community/x86_64/libvirt-libs-8.9.0-r4.apk
42f2618b35e9404d64f752c22f9cd2cb7a7d72328ceff4292b0a2a6be355fdc6 v3.17/main/x86_64/libffi-3.4.4-r0.apk
ecca312cb85b634352aef41f1561f3f3f262e85b57a620859df2d0cbe6972ded v3.17/main/x86_64/libtasn1-4.19.0-r0.apk
3a8a2279188d4aa769448c0b9cc66b189158b3c60a29d20384ba4e44ed64ded7 v3.17/main/x86_64/libssl3-3.0.8-r1.apk
f9585399e58c15da6324f92e7ad92a757c01edb560e9c362ab4587c6158cd8e4 v3.17/main/x86_64/libverto-glib-0.3.2-r1.apk
455c58e9b66da6d7fe4b86cd9bab830e3963008b58bd87fe0e6b7aa05907af4c v3.17/main/x86_64/pkgconf-1.9.4-r0.apk
27479b796bc8380af06dca70451ecd08c2ac87e0020b4352398535a7c8cf746e v3.17/main/x86_64/bsd-compat-headers-0.7.2-r3.apk
@ -25,6 +24,7 @@ f13865c26ebde846324dccea96d85f00a4a4d17338ff222e5cd80b8672e02247 v3.17/main/x86
5c0be2a5a9bc708afe8dc94c9da40c66f4c22505d236ef163aa292a4cde159a6 v3.17/main/x86_64/libattr-2.5.1-r2.apk
51df3c3934695e14b222a293a720e087214f1d3980ccc40bb2e2c706b62de43f v3.17/main/x86_64/libcom_err-1.46.6-r0.apk
2564f7bb9985495a12b30a283acd53ad1c5e742b405bba2a031581eaac94b8f9 v3.17/main/x86_64/lzip-1.23-r0.apk
6c17cdfebebe34bd50e871b1d68b1b8d85d64a068c54288b0953221713b51a6c v3.17/main/x86_64/alpine-conf-3.15.1-r1.apk
6ca645108699bcbf917dfdf4fdfe4eb48e1f407ea048098709d20e865109ecfc v3.17/main/x86_64/libev-4.33-r0.apk
bdc90400c34b17772e2713154c3e4c34a8db37edace1e6dc8f07329eb09f4ac9 v3.17/main/x86_64/libintl-0.21.1-r1.apk
ede0b4fa32c44ed13ef23616856f173d6f9fd7de1787426e8009cbd04f03802d v3.17/main/x86_64/libnl3-3.7.0-r0.apk
@ -39,7 +39,6 @@ a51399a9415101a98ffee5921fdf3fc24308c37e30cb4afe3c89ef9cf1da9bc7 v3.17/main/x86
a84e314c5e4f63c391c1074f74063597b20e4a4eddae47064bd46a22b1ef8d87 v3.17/main/x86_64/krb5-dev-1.20.1-r0.apk
ed5b7c94e805c94306ec6411ddc1b2b67b94336b5b9a218967f4e55daad7313b v3.17/main/x86_64/busybox-suid-1.35.0-r29.apk
b1b3ac001c198712c2798ec70b8bb6245b06cdee342a4622f371f7df043ab82c v3.17/main/x86_64/libblkid-2.38.1-r1.apk
3c5a74dd9fc57ac4941cb716a89c8dcad101f93b6b3cd9b38d22ba62ccd1c142 v3.17/main/x86_64/alpine-conf-3.15.1-r0.apk
6c799e4779fb3cb018265293f1ba6047282cddd4a17312960ad695f8830f3a5b v3.17/main/x86_64/libc-utils-0.7.2-r3.apk
2a46230e00ba2e1c59c4d3dfc4bd74135d034191dc9fdf6606b3021c00efb5d3 v3.17/main/x86_64/mdev-conf-4.3-r0.apk
afcc0a285b823f73526c1995cf9ce71f91fc99ce0969a3494926df94e2589e68 v3.17/main/x86_64/ca-certificates-bundle-20220614-r4.apk
@ -58,18 +57,19 @@ dc35929a53b3abaecb69b18dca79af25e38b8ab906aec5a912ec120b2cb4b731 v3.17/main/x86
d43569a2293a79ae7b7ee7d36f14b3f9893301a971e8534d104fa51a160b9607 v3.17/main/x86_64/libunistring-1.1-r0.apk
82874c31d2fc4aa5bb2c3e7240d419643c20c5740e1f2c91099b6f04aad200ad v3.17/main/x86_64/nghttp2-libs-1.51.0-r0.apk
2a77f358c803ae9e2ec35ccf4906019df9b92d96c13e207d92ccabd13aec80eb v3.17/main/x86_64/musl-1.2.3-r4.apk
31db30def1c7d768d7656ff2a6a03550258675fdb9eedf9e0cf9dca999bd9273 v3.17/main/x86_64/patch-2.7.6-r8.apk
ac29bb040470e672d186c62bd9db5b7f0d29336b5992f024098a951754f43a22 v3.17/main/x86_64/apk-tools-2.12.10-r1.apk
baa3e5a7f248f0e34bcaa07b2c5dfbe39641e52feb878518cd6a7f6c579590e9 v3.17/main/x86_64/patch-2.7.6-r9.apk
adfebf5fc4004f1460f5971913fcca3ea3d6fa56412d32ffc48f191e336a1cc5 v3.17/main/x86_64/libcap-ng-0.8.3-r1.apk
a1060409c38e4d67e6ce67001108a35c2ade5a50cdff9c62fc555ef9a08717b9 v3.17/main/x86_64/libverto-libev-0.3.2-r1.apk
9c75bacd5d9b5c41c451813afd7aa35e209537d44d6b0b944a5738a83d088934 v3.17/main/x86_64/libssl3-3.0.8-r2.apk
6643e122290e4485cfbb7dae52d11ad1d48c19f5f34a6549af0da1ce9974dfd1 v3.17/main/x86_64/alpine-release-3.17.2-r0.apk
74b244c1baaa58f1c41519aea3025a696dbaaac5d912c1bc3029437bea9b2b38 v3.17/main/x86_64/openssl-3.0.8-r2.apk
862e8d30f9be1a41632c7c575fbc8f81199a5fda650bc47384422bc017e09c4d v3.17/main/x86_64/keyutils-libs-1.6.3-r1.apk
935589dfe902b26cdbe09f54eb399ce2f5d6b5e13eb994de36abb495e4843df5 v3.17/main/x86_64/yajl-2.1.0-r5.apk
fee7860a5a1cb324bfe5ee4b5a68e834d57862743f062183681443e3387951da v3.17/main/x86_64/libverto-libevent-0.3.2-r1.apk
3f922d7d8dafdae6710d9d8bdc96eb72ed4d0a8192b39eda797034e00f38263e v3.17/main/x86_64/alpine-baselayout-3.4.0-r0.apk
38d2e91f7a59de07375655b8f1cd12a3ffa4d1f6c7afc8bd726ee0496aa62fe9 v3.17/main/x86_64/gnutls-3.7.8-r3.apk
c727fa15838b10908282453e3869081d3e93298dc6b55d45a4c3a48a89a676eb v3.17/main/x86_64/libsmartcols-2.38.1-r1.apk
5f34ba03402e656ca0692257faba31233eee11c7db717db541451dc39b4a7a62 v3.17/main/x86_64/libcrypto3-3.0.8-r1.apk
3013bcbddf3ff9eb812791a2e87fc2a0b72910cfd415590d21faa96d3bbbf1bc v3.17/main/x86_64/libuuid-2.38.1-r1.apk
b51a7d5da574c6ecd2fc8bb711ea8d47e29875f0eb66ce6dc47f5fe53deeda47 v3.17/main/x86_64/gmp-6.2.1-r2.apk
b6f3592eb4fa228a8221f2b405cedbfe8fcadef07a7903a57d8e460af753fe48 v3.17/main/x86_64/nettle-3.8.1-r0.apk
@ -79,7 +79,6 @@ b6f3592eb4fa228a8221f2b405cedbfe8fcadef07a7903a57d8e460af753fe48 v3.17/main/x86
353f5caae4a1bcc06a0b44e540e5cec4740216482ec727121fd309ccfa150bf6 v3.17/main/x86_64/libldap-2.6.3-r6.apk
966af3c474ca42d4a367b7d62ec9e80576e30a60198f9646a933b816769f6c7c v3.17/main/x86_64/curl-7.88.1-r1.apk
17af2d1ba520e8bf31c39f4756786ebe84faf89be852bc874f4adf56296ed896 v3.17/main/x86_64/libacl-2.3.1-r1.apk
11047ab0871370919fc65e918ba411873ce37510251ce33dd6d085c584afa052 v3.17/main/x86_64/openssl-3.0.8-r1.apk
495a88687dbc7a63e44c6555f1b6aca6ba80f772d359623f4da5edc362afae08 v3.17/main/x86_64/libstdc++-12.2.1_git20220924-r4.apk
f8239d8d4e8961e76e2e95caf9b6d2d89816b6f2562f7551aa8eb26c2268c6d6 v3.17/main/x86_64/busybox-openrc-1.35.0-r29.apk
0d5bc88d04d7da3ad800f4dcaee4b7876c9c6ff3d2537a7b3471e4f488b5a5f0 v3.17/main/x86_64/libxml2-2.10.3-r1.apk
@ -87,3 +86,4 @@ b413e1c8b38b53fb83ecc7b75a227aa7b520a9dac80f0d7c1fc912bc56416c2a v3.17/main/x86
2c0282ec5c2d78fe94b1e0ab676d6fe675e6656796b8a92e29ce4b17234add6a v3.17/main/x86_64/libgcc-12.2.1_git20220924-r4.apk
736d8808f17603015b7766e0f88c703451cba97d987dfd1c92ceed7b55ecf24d v3.17/main/x86_64/ifupdown-ng-0.12.1-r1.apk
f401d78b65a5067ef396c93a56950a87fa1b1fe3e1770489021f5924db7b10b0 v3.17/main/x86_64/libverto-0.3.2-r1.apk
2384fa191f9a2c676dc2d898f8a8f64fd62dac8ab2dbe00c515b2165120a82a1 v3.17/main/x86_64/libcrypto3-3.0.8-r2.apk

View File

@ -28,16 +28,16 @@ def go_dependencies():
build_file_generation = "on",
build_file_proto_mode = "disable_global",
importpath = "mvdan.cc/unparam",
sum = "h1:Jh3LAeMt1eGpxomyu3jVkmVZWW2MxZ1qIIV2TZ/nRio=",
version = "v0.0.0-20211214103731-d0ef000c54e5",
sum = "h1:VuJo4Mt0EVPychre4fNlDWDuE5AjXtPJpRUWqZDQhaI=",
version = "v0.0.0-20230312165513-e84e2d14e3b8",
)
go_repository(
name = "co_honnef_go_tools",
build_file_generation = "on",
build_file_proto_mode = "disable_global",
importpath = "honnef.co/go/tools",
sum = "h1:MNh1AVMyVX23VUHE2O27jm6lNj3vjO5DexS4A1xvnzk=",
version = "v0.2.2",
sum = "h1:o/n5/K5gXqk8Gozvs2cnL0F2S1/g1vcGCAx2vETjITw=",
version = "v0.4.3",
)
go_repository(
name = "com_github_acomagu_bufpipe",
@ -2976,8 +2976,8 @@ def go_dependencies():
build_file_generation = "on",
build_file_proto_mode = "disable_global",
importpath = "github.com/gophercloud/utils",
sum = "h1:g9xk/61NXFpeG7zEReUsv2VeQRux1dXhT/xGHtJD/mA=",
version = "v0.0.0-20230316075016-e15d7ee3ba3b",
sum = "h1:AfRlf5NnsYsHIW5nNxhYp+99Bmj/fLeOYwD5Z4CMlzw=",
version = "v0.0.0-20230324070755-05e9e7f5ea4d",
)
go_repository(
@ -8448,6 +8448,15 @@ def go_dependencies():
sum = "h1:S4NrSKDfihhl3+4jSTgwoIevKxX9p7Iv9x++OEIptDo=",
version = "v0.0.0-20220823124025-807a23277127",
)
go_repository(
name = "org_golang_x_exp_typeparams",
build_file_generation = "on",
build_file_proto_mode = "disable_global",
importpath = "golang.org/x/exp/typeparams",
sum = "h1:Jw5wfR+h9mnIYH+OtGT2im5wV1YGGDora5vTv/aa5bE=",
version = "v0.0.0-20221208152030-732eee02a75a",
)
go_repository(
name = "org_golang_x_image",
build_file_generation = "on",
@ -8477,8 +8486,8 @@ def go_dependencies():
build_file_generation = "on",
build_file_proto_mode = "disable_global",
importpath = "golang.org/x/mod",
sum = "h1:LUYupSeNrTNCGzR/hVBk2NHZO4hXcVaW1k4Qx7rjPx8=",
version = "v0.8.0",
sum = "h1:KENHtAZL2y3NLMYZeHY9DW8HW8V+kQyJsY/V9JlKvCs=",
version = "v0.9.0",
)
go_repository(
name = "org_golang_x_net",
@ -8541,16 +8550,16 @@ def go_dependencies():
build_file_generation = "on",
build_file_proto_mode = "disable_global",
importpath = "golang.org/x/tools",
sum = "h1:IuFp2CklNBim6OdHXn/1P4VoeKt5pA2jcDKWlboqtlQ=",
version = "v0.6.1-0.20230217175706-3102dad5faf9",
sum = "h1:W4OVu8VVOaIO0yzWMNdepAulS7YfoS3Zabrm8DOXXU4=",
version = "v0.7.0",
)
go_repository(
name = "org_golang_x_vuln",
build_file_generation = "on",
build_file_proto_mode = "disable_global",
importpath = "golang.org/x/vuln",
sum = "h1:D+fLQz4/9B7Fdtbh8DpmoYjuVukotDPky6ZDsFtiVwk=",
version = "v0.0.0-20230322160202-f2d9b5a6e023",
sum = "h1:ioRvkxpf+3iq9xvzP6AWjaBuROUad9SmjLr0QWBzxKw=",
version = "v0.0.0-20230325131008-9550759f8614",
)
go_repository(

View File

@ -23,7 +23,6 @@ go_library(
"//bootstrapper/internal/nodelock",
"//internal/atls",
"//internal/attestation/choose",
"//internal/attestation/measurements",
"//internal/attestation/simulator",
"//internal/attestation/vtpm",
"//internal/cloud/aws",
@ -38,8 +37,8 @@ go_library(
"//internal/grpc/dialer",
"//internal/kubernetes/kubectl",
"//internal/logger",
"//internal/oid",
"//internal/role",
"//internal/variant",
"//internal/versions/components",
"@com_github_spf13_afero//:afero",
"@io_k8s_kubernetes//cmd/kubeadm/app/apis/kubeadm/v1beta3",

View File

@ -19,7 +19,6 @@ import (
"github.com/edgelesssys/constellation/v2/bootstrapper/internal/kubernetes/kubewaiter"
"github.com/edgelesssys/constellation/v2/bootstrapper/internal/logging"
"github.com/edgelesssys/constellation/v2/internal/attestation/choose"
"github.com/edgelesssys/constellation/v2/internal/attestation/measurements"
"github.com/edgelesssys/constellation/v2/internal/attestation/simulator"
"github.com/edgelesssys/constellation/v2/internal/attestation/vtpm"
awscloud "github.com/edgelesssys/constellation/v2/internal/cloud/aws"
@ -32,7 +31,7 @@ import (
"github.com/edgelesssys/constellation/v2/internal/file"
"github.com/edgelesssys/constellation/v2/internal/kubernetes/kubectl"
"github.com/edgelesssys/constellation/v2/internal/logger"
"github.com/edgelesssys/constellation/v2/internal/oid"
"github.com/edgelesssys/constellation/v2/internal/variant"
"github.com/spf13/afero"
"go.uber.org/zap"
)
@ -71,7 +70,7 @@ func main() {
log.With(zap.Error(err)).Fatalf("Helm client could not be initialized")
}
attestVariant, err := oid.FromString(os.Getenv(constants.AttestationVariant))
attestVariant, err := variant.FromString(os.Getenv(constants.AttestationVariant))
if err != nil {
log.With(zap.Error(err)).Fatalf("Failed to parse attestation variant")
}
@ -82,11 +81,6 @@ func main() {
switch cloudprovider.FromString(os.Getenv(constellationCSP)) {
case cloudprovider.AWS:
measurements, err := vtpm.GetSelectedMeasurements(vtpm.OpenVTPM, vtpm.AWSPCRSelection)
if err != nil {
log.With(zap.Error(err)).Fatalf("Failed to get selected PCRs")
}
metadata, err := awscloud.New(ctx)
if err != nil {
log.With(zap.Error(err)).Fatalf("Failed to set up AWS metadata API")
@ -100,17 +94,12 @@ func main() {
clusterInitJoiner = kubernetes.New(
"aws", k8sapi.NewKubernetesUtil(), &k8sapi.KubdeadmConfiguration{}, kubectl.New(),
metadata, measurements, helmClient, &kubewaiter.CloudKubeAPIWaiter{},
metadata, helmClient, &kubewaiter.CloudKubeAPIWaiter{},
)
openTPM = vtpm.OpenVTPM
fs = afero.NewOsFs()
case cloudprovider.GCP:
measurements, err := vtpm.GetSelectedMeasurements(vtpm.OpenVTPM, vtpm.GCPPCRSelection)
if err != nil {
log.With(zap.Error(err)).Fatalf("Failed to get selected PCRs")
}
metadata, err := gcpcloud.New(ctx)
if err != nil {
log.With(zap.Error(err)).Fatalf("Failed to create GCP metadata client")
@ -125,18 +114,13 @@ func main() {
metadataAPI = metadata
clusterInitJoiner = kubernetes.New(
"gcp", k8sapi.NewKubernetesUtil(), &k8sapi.KubdeadmConfiguration{}, kubectl.New(),
metadata, measurements, helmClient, &kubewaiter.CloudKubeAPIWaiter{},
metadata, helmClient, &kubewaiter.CloudKubeAPIWaiter{},
)
openTPM = vtpm.OpenVTPM
fs = afero.NewOsFs()
log.Infof("Added load balancer IP to routing table")
case cloudprovider.Azure:
measurements, err := vtpm.GetSelectedMeasurements(vtpm.OpenVTPM, vtpm.AzurePCRSelection)
if err != nil {
log.With(zap.Error(err)).Fatalf("Failed to get selected PCRs")
}
metadata, err := azurecloud.New(ctx)
if err != nil {
log.With(zap.Error(err)).Fatalf("Failed to create Azure metadata client")
@ -148,34 +132,24 @@ func main() {
metadataAPI = metadata
clusterInitJoiner = kubernetes.New(
"azure", k8sapi.NewKubernetesUtil(), &k8sapi.KubdeadmConfiguration{}, kubectl.New(),
metadata, measurements, helmClient, &kubewaiter.CloudKubeAPIWaiter{},
metadata, helmClient, &kubewaiter.CloudKubeAPIWaiter{},
)
openTPM = vtpm.OpenVTPM
fs = afero.NewOsFs()
case cloudprovider.QEMU:
measurements, err := vtpm.GetSelectedMeasurements(vtpm.OpenVTPM, vtpm.QEMUPCRSelection)
if err != nil {
log.With(zap.Error(err)).Fatalf("Failed to get selected PCRs")
}
cloudLogger = qemucloud.NewLogger()
metadata := qemucloud.New()
clusterInitJoiner = kubernetes.New(
"qemu", k8sapi.NewKubernetesUtil(), &k8sapi.KubdeadmConfiguration{}, kubectl.New(),
metadata, measurements, helmClient, &kubewaiter.CloudKubeAPIWaiter{},
metadata, helmClient, &kubewaiter.CloudKubeAPIWaiter{},
)
metadataAPI = metadata
openTPM = vtpm.OpenVTPM
fs = afero.NewOsFs()
case cloudprovider.OpenStack:
// TODO(malt3): add OpenStack TPM support
measurements := measurements.M{
15: measurements.WithAllBytes(0x0, measurements.WarnOnly),
}
cloudLogger = &logging.NopLogger{}
metadata, err := openstackcloud.New(ctx)
if err != nil {
@ -183,7 +157,7 @@ func main() {
}
clusterInitJoiner = kubernetes.New(
"openstack", k8sapi.NewKubernetesUtil(), &k8sapi.KubdeadmConfiguration{}, kubectl.New(),
metadata, measurements, helmClient, &kubewaiter.CloudKubeAPIWaiter{},
metadata, helmClient, &kubewaiter.CloudKubeAPIWaiter{},
)
metadataAPI = metadata

View File

@ -21,7 +21,7 @@ type clusterFake struct{}
// InitCluster fakes bootstrapping a new cluster with the current node being the master, returning the arguments required to join the cluster.
func (c *clusterFake) InitCluster(
context.Context, string, string, string, []byte, []uint32,
context.Context, string, string, string, []byte,
[]byte, bool, components.Components, *logger.Logger,
) ([]byte, error) {
return []byte{}, nil

View File

@ -36,7 +36,7 @@ type InitRequest struct {
// repeated SSHUserKey ssh_user_keys = 9; removed
// bytes salt = 10; removed
HelmDeployments []byte `protobuf:"bytes,11,opt,name=helm_deployments,json=helmDeployments,proto3" json:"helm_deployments,omitempty"`
EnforcedPcrs []uint32 `protobuf:"varint,12,rep,packed,name=enforced_pcrs,json=enforcedPcrs,proto3" json:"enforced_pcrs,omitempty"`
// repeated uint32 enforced_pcrs = 12; removed
// bool enforce_idkeydigest = 13; removed
ConformanceMode bool `protobuf:"varint,14,opt,name=conformance_mode,json=conformanceMode,proto3" json:"conformance_mode,omitempty"`
KubernetesComponents []*KubernetesComponent `protobuf:"bytes,15,rep,name=kubernetes_components,json=kubernetesComponents,proto3" json:"kubernetes_components,omitempty"`
@ -111,13 +111,6 @@ func (x *InitRequest) GetHelmDeployments() []byte {
return nil
}
func (x *InitRequest) GetEnforcedPcrs() []uint32 {
if x != nil {
return x.EnforcedPcrs
}
return nil
}
func (x *InitRequest) GetConformanceMode() bool {
if x != nil {
return x.ConformanceMode
@ -284,7 +277,7 @@ var File_init_proto protoreflect.FileDescriptor
var file_init_proto_rawDesc = []byte{
0x0a, 0x0a, 0x69, 0x6e, 0x69, 0x74, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x04, 0x69, 0x6e,
0x69, 0x74, 0x22, 0xc0, 0x03, 0x0a, 0x0b, 0x49, 0x6e, 0x69, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65,
0x69, 0x74, 0x22, 0x9b, 0x03, 0x0a, 0x0b, 0x49, 0x6e, 0x69, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65,
0x73, 0x74, 0x12, 0x17, 0x0a, 0x07, 0x6b, 0x6d, 0x73, 0x5f, 0x75, 0x72, 0x69, 0x18, 0x03, 0x20,
0x01, 0x28, 0x09, 0x52, 0x06, 0x6b, 0x6d, 0x73, 0x55, 0x72, 0x69, 0x12, 0x1f, 0x0a, 0x0b, 0x73,
0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x5f, 0x75, 0x72, 0x69, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09,
@ -298,43 +291,41 @@ var file_init_proto_rawDesc = []byte{
0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x29, 0x0a, 0x10, 0x68, 0x65, 0x6c, 0x6d, 0x5f, 0x64,
0x65, 0x70, 0x6c, 0x6f, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x0c,
0x52, 0x0f, 0x68, 0x65, 0x6c, 0x6d, 0x44, 0x65, 0x70, 0x6c, 0x6f, 0x79, 0x6d, 0x65, 0x6e, 0x74,
0x73, 0x12, 0x23, 0x0a, 0x0d, 0x65, 0x6e, 0x66, 0x6f, 0x72, 0x63, 0x65, 0x64, 0x5f, 0x70, 0x63,
0x72, 0x73, 0x18, 0x0c, 0x20, 0x03, 0x28, 0x0d, 0x52, 0x0c, 0x65, 0x6e, 0x66, 0x6f, 0x72, 0x63,
0x65, 0x64, 0x50, 0x63, 0x72, 0x73, 0x12, 0x29, 0x0a, 0x10, 0x63, 0x6f, 0x6e, 0x66, 0x6f, 0x72,
0x6d, 0x61, 0x6e, 0x63, 0x65, 0x5f, 0x6d, 0x6f, 0x64, 0x65, 0x18, 0x0e, 0x20, 0x01, 0x28, 0x08,
0x52, 0x0f, 0x63, 0x6f, 0x6e, 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x6e, 0x63, 0x65, 0x4d, 0x6f, 0x64,
0x65, 0x12, 0x4e, 0x0a, 0x15, 0x6b, 0x75, 0x62, 0x65, 0x72, 0x6e, 0x65, 0x74, 0x65, 0x73, 0x5f,
0x63, 0x6f, 0x6d, 0x70, 0x6f, 0x6e, 0x65, 0x6e, 0x74, 0x73, 0x18, 0x0f, 0x20, 0x03, 0x28, 0x0b,
0x32, 0x19, 0x2e, 0x69, 0x6e, 0x69, 0x74, 0x2e, 0x4b, 0x75, 0x62, 0x65, 0x72, 0x6e, 0x65, 0x74,
0x65, 0x73, 0x43, 0x6f, 0x6d, 0x70, 0x6f, 0x6e, 0x65, 0x6e, 0x74, 0x52, 0x14, 0x6b, 0x75, 0x62,
0x65, 0x72, 0x6e, 0x65, 0x74, 0x65, 0x73, 0x43, 0x6f, 0x6d, 0x70, 0x6f, 0x6e, 0x65, 0x6e, 0x74,
0x73, 0x12, 0x1f, 0x0a, 0x0b, 0x69, 0x6e, 0x69, 0x74, 0x5f, 0x73, 0x65, 0x63, 0x72, 0x65, 0x74,
0x18, 0x10, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0a, 0x69, 0x6e, 0x69, 0x74, 0x53, 0x65, 0x63, 0x72,
0x65, 0x74, 0x12, 0x21, 0x0a, 0x0c, 0x63, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x5f, 0x6e, 0x61,
0x6d, 0x65, 0x18, 0x11, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x63, 0x6c, 0x75, 0x73, 0x74, 0x65,
0x72, 0x4e, 0x61, 0x6d, 0x65, 0x22, 0x68, 0x0a, 0x0c, 0x49, 0x6e, 0x69, 0x74, 0x52, 0x65, 0x73,
0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x1e, 0x0a, 0x0a, 0x6b, 0x75, 0x62, 0x65, 0x63, 0x6f, 0x6e,
0x66, 0x69, 0x67, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0a, 0x6b, 0x75, 0x62, 0x65, 0x63,
0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x19, 0x0a, 0x08, 0x6f, 0x77, 0x6e, 0x65, 0x72, 0x5f, 0x69,
0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x07, 0x6f, 0x77, 0x6e, 0x65, 0x72, 0x49, 0x64,
0x12, 0x1d, 0x0a, 0x0a, 0x63, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x18, 0x03,
0x20, 0x01, 0x28, 0x0c, 0x52, 0x09, 0x63, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x49, 0x64, 0x22,
0x78, 0x0a, 0x13, 0x4b, 0x75, 0x62, 0x65, 0x72, 0x6e, 0x65, 0x74, 0x65, 0x73, 0x43, 0x6f, 0x6d,
0x70, 0x6f, 0x6e, 0x65, 0x6e, 0x74, 0x12, 0x10, 0x0a, 0x03, 0x75, 0x72, 0x6c, 0x18, 0x01, 0x20,
0x01, 0x28, 0x09, 0x52, 0x03, 0x75, 0x72, 0x6c, 0x12, 0x12, 0x0a, 0x04, 0x68, 0x61, 0x73, 0x68,
0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x68, 0x61, 0x73, 0x68, 0x12, 0x21, 0x0a, 0x0c,
0x69, 0x6e, 0x73, 0x74, 0x61, 0x6c, 0x6c, 0x5f, 0x70, 0x61, 0x74, 0x68, 0x18, 0x03, 0x20, 0x01,
0x28, 0x09, 0x52, 0x0b, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6c, 0x6c, 0x50, 0x61, 0x74, 0x68, 0x12,
0x18, 0x0a, 0x07, 0x65, 0x78, 0x74, 0x72, 0x61, 0x63, 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, 0x08,
0x52, 0x07, 0x65, 0x78, 0x74, 0x72, 0x61, 0x63, 0x74, 0x32, 0x34, 0x0a, 0x03, 0x41, 0x50, 0x49,
0x12, 0x2d, 0x0a, 0x04, 0x49, 0x6e, 0x69, 0x74, 0x12, 0x11, 0x2e, 0x69, 0x6e, 0x69, 0x74, 0x2e,
0x49, 0x6e, 0x69, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x12, 0x2e, 0x69, 0x6e,
0x69, 0x74, 0x2e, 0x49, 0x6e, 0x69, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x42,
0x40, 0x5a, 0x3e, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x65, 0x64,
0x67, 0x65, 0x6c, 0x65, 0x73, 0x73, 0x73, 0x79, 0x73, 0x2f, 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x65,
0x6c, 0x6c, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2f, 0x76, 0x32, 0x2f, 0x62, 0x6f, 0x6f, 0x74, 0x73,
0x74, 0x72, 0x61, 0x70, 0x70, 0x65, 0x72, 0x2f, 0x69, 0x6e, 0x69, 0x74, 0x70, 0x72, 0x6f, 0x74,
0x6f, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
0x73, 0x12, 0x29, 0x0a, 0x10, 0x63, 0x6f, 0x6e, 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x6e, 0x63, 0x65,
0x5f, 0x6d, 0x6f, 0x64, 0x65, 0x18, 0x0e, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0f, 0x63, 0x6f, 0x6e,
0x66, 0x6f, 0x72, 0x6d, 0x61, 0x6e, 0x63, 0x65, 0x4d, 0x6f, 0x64, 0x65, 0x12, 0x4e, 0x0a, 0x15,
0x6b, 0x75, 0x62, 0x65, 0x72, 0x6e, 0x65, 0x74, 0x65, 0x73, 0x5f, 0x63, 0x6f, 0x6d, 0x70, 0x6f,
0x6e, 0x65, 0x6e, 0x74, 0x73, 0x18, 0x0f, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x69, 0x6e,
0x69, 0x74, 0x2e, 0x4b, 0x75, 0x62, 0x65, 0x72, 0x6e, 0x65, 0x74, 0x65, 0x73, 0x43, 0x6f, 0x6d,
0x70, 0x6f, 0x6e, 0x65, 0x6e, 0x74, 0x52, 0x14, 0x6b, 0x75, 0x62, 0x65, 0x72, 0x6e, 0x65, 0x74,
0x65, 0x73, 0x43, 0x6f, 0x6d, 0x70, 0x6f, 0x6e, 0x65, 0x6e, 0x74, 0x73, 0x12, 0x1f, 0x0a, 0x0b,
0x69, 0x6e, 0x69, 0x74, 0x5f, 0x73, 0x65, 0x63, 0x72, 0x65, 0x74, 0x18, 0x10, 0x20, 0x01, 0x28,
0x0c, 0x52, 0x0a, 0x69, 0x6e, 0x69, 0x74, 0x53, 0x65, 0x63, 0x72, 0x65, 0x74, 0x12, 0x21, 0x0a,
0x0c, 0x63, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x11, 0x20,
0x01, 0x28, 0x09, 0x52, 0x0b, 0x63, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x4e, 0x61, 0x6d, 0x65,
0x22, 0x68, 0x0a, 0x0c, 0x49, 0x6e, 0x69, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65,
0x12, 0x1e, 0x0a, 0x0a, 0x6b, 0x75, 0x62, 0x65, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x18, 0x01,
0x20, 0x01, 0x28, 0x0c, 0x52, 0x0a, 0x6b, 0x75, 0x62, 0x65, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67,
0x12, 0x19, 0x0a, 0x08, 0x6f, 0x77, 0x6e, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01,
0x28, 0x0c, 0x52, 0x07, 0x6f, 0x77, 0x6e, 0x65, 0x72, 0x49, 0x64, 0x12, 0x1d, 0x0a, 0x0a, 0x63,
0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0c, 0x52,
0x09, 0x63, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x49, 0x64, 0x22, 0x78, 0x0a, 0x13, 0x4b, 0x75,
0x62, 0x65, 0x72, 0x6e, 0x65, 0x74, 0x65, 0x73, 0x43, 0x6f, 0x6d, 0x70, 0x6f, 0x6e, 0x65, 0x6e,
0x74, 0x12, 0x10, 0x0a, 0x03, 0x75, 0x72, 0x6c, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03,
0x75, 0x72, 0x6c, 0x12, 0x12, 0x0a, 0x04, 0x68, 0x61, 0x73, 0x68, 0x18, 0x02, 0x20, 0x01, 0x28,
0x09, 0x52, 0x04, 0x68, 0x61, 0x73, 0x68, 0x12, 0x21, 0x0a, 0x0c, 0x69, 0x6e, 0x73, 0x74, 0x61,
0x6c, 0x6c, 0x5f, 0x70, 0x61, 0x74, 0x68, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x69,
0x6e, 0x73, 0x74, 0x61, 0x6c, 0x6c, 0x50, 0x61, 0x74, 0x68, 0x12, 0x18, 0x0a, 0x07, 0x65, 0x78,
0x74, 0x72, 0x61, 0x63, 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, 0x08, 0x52, 0x07, 0x65, 0x78, 0x74,
0x72, 0x61, 0x63, 0x74, 0x32, 0x34, 0x0a, 0x03, 0x41, 0x50, 0x49, 0x12, 0x2d, 0x0a, 0x04, 0x49,
0x6e, 0x69, 0x74, 0x12, 0x11, 0x2e, 0x69, 0x6e, 0x69, 0x74, 0x2e, 0x49, 0x6e, 0x69, 0x74, 0x52,
0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x12, 0x2e, 0x69, 0x6e, 0x69, 0x74, 0x2e, 0x49, 0x6e,
0x69, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x42, 0x40, 0x5a, 0x3e, 0x67, 0x69,
0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x65, 0x64, 0x67, 0x65, 0x6c, 0x65, 0x73,
0x73, 0x73, 0x79, 0x73, 0x2f, 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x65, 0x6c, 0x6c, 0x61, 0x74, 0x69,
0x6f, 0x6e, 0x2f, 0x76, 0x32, 0x2f, 0x62, 0x6f, 0x6f, 0x74, 0x73, 0x74, 0x72, 0x61, 0x70, 0x70,
0x65, 0x72, 0x2f, 0x69, 0x6e, 0x69, 0x74, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x06, 0x70, 0x72,
0x6f, 0x74, 0x6f, 0x33,
}
var (

View File

@ -20,7 +20,7 @@ message InitRequest {
// repeated SSHUserKey ssh_user_keys = 9; removed
// bytes salt = 10; removed
bytes helm_deployments = 11;
repeated uint32 enforced_pcrs = 12;
// repeated uint32 enforced_pcrs = 12; removed
// bool enforce_idkeydigest = 13; removed
bool conformance_mode = 14;
repeated KubernetesComponent kubernetes_components = 15;

View File

@ -44,7 +44,7 @@ go_test(
"//internal/kms/setup",
"//internal/kms/uri",
"//internal/logger",
"//internal/oid",
"//internal/variant",
"//internal/versions/components",
"@com_github_spf13_afero//:afero",
"@com_github_stretchr_testify//assert",

View File

@ -177,7 +177,6 @@ func (s *Server) Init(ctx context.Context, req *initproto.InitRequest) (*initpro
req.KubernetesVersion,
clusterName,
measurementSalt,
req.EnforcedPcrs,
req.HelmDeployments,
req.ConformanceMode,
components.NewComponentsFromInitProto(req.KubernetesComponents),
@ -252,7 +251,6 @@ type ClusterInitializer interface {
k8sVersion string,
clusterName string,
measurementSalt []byte,
enforcedPcrs []uint32,
helmDeployments []byte,
conformanceMode bool,
kubernetesComponents components.Components,

View File

@ -22,7 +22,7 @@ import (
kmssetup "github.com/edgelesssys/constellation/v2/internal/kms/setup"
"github.com/edgelesssys/constellation/v2/internal/kms/uri"
"github.com/edgelesssys/constellation/v2/internal/logger"
"github.com/edgelesssys/constellation/v2/internal/oid"
"github.com/edgelesssys/constellation/v2/internal/variant"
"github.com/edgelesssys/constellation/v2/internal/versions/components"
"github.com/spf13/afero"
"github.com/stretchr/testify/assert"
@ -62,7 +62,7 @@ func TestNew(t *testing.T) {
t.Run(name, func(t *testing.T) {
assert := assert.New(t)
server, err := New(context.TODO(), newFakeLock(), &stubClusterInitializer{}, atls.NewFakeIssuer(oid.Dummy{}), fh, &tc.metadata, logger.NewTest(t))
server, err := New(context.TODO(), newFakeLock(), &stubClusterInitializer{}, atls.NewFakeIssuer(variant.Dummy{}), fh, &tc.metadata, logger.NewTest(t))
if tc.wantErr {
assert.Error(err)
return
@ -320,7 +320,7 @@ type stubClusterInitializer struct {
}
func (i *stubClusterInitializer) InitCluster(
context.Context, string, string, string, []byte, []uint32,
context.Context, string, string, string, []byte,
[]byte, bool, components.Components, *logger.Logger,
) ([]byte, error) {
return i.initClusterKubeconfig, i.initClusterErr

View File

@ -0,0 +1,16 @@
load("@io_bazel_rules_go//go:def.bzl", "go_library")
load("//bazel/go:go_test.bzl", "go_test")
go_library(
name = "journald",
srcs = ["journald.go"],
importpath = "github.com/edgelesssys/constellation/v2/bootstrapper/internal/journald",
visibility = ["//bootstrapper:__subpackages__"],
)
go_test(
name = "journald_test",
srcs = ["journald_test.go"],
embed = [":journald"],
deps = ["@com_github_stretchr_testify//assert"],
)

View File

@ -0,0 +1,47 @@
/*
Copyright (c) Edgeless Systems GmbH
SPDX-License-Identifier: AGPL-3.0-only
*/
/*
Package journald provides functions to read and collect journald logs.
*/
package journald
import (
"context"
"errors"
"fmt"
"os/exec"
)
type command interface {
Output() ([]byte, error)
}
// Collector collects logs from journald.
type Collector struct {
cmd command
}
// NewCollector creates a new Collector for journald logs.
func NewCollector(ctx context.Context) (*Collector, error) {
cmd := exec.CommandContext(ctx, "journalctl")
if cmd.Err != nil {
return nil, cmd.Err
}
return &Collector{cmd}, nil
}
// Collect gets all journald logs from a service and returns a byte slice with the plain text logs.
func (c *Collector) Collect() ([]byte, error) {
out, err := c.cmd.Output()
var exitErr *exec.ExitError
if errors.As(err, &exitErr) {
return nil, fmt.Errorf("executing %q failed: %s", c.cmd, exitErr.Stderr)
} else if err != nil {
return nil, fmt.Errorf("executing command: %w", err)
}
return out, nil
}

View File

@ -0,0 +1,64 @@
/*
Copyright (c) Edgeless Systems GmbH
SPDX-License-Identifier: AGPL-3.0-only
*/
package journald
import (
"errors"
"os/exec"
"testing"
"github.com/stretchr/testify/assert"
)
type stubJournaldCommand struct {
outputReturn []byte
outputError error
}
func (j *stubJournaldCommand) Output() ([]byte, error) {
return j.outputReturn, j.outputError
}
func TestCollect(t *testing.T) {
someError := errors.New("failed")
testCases := map[string]struct {
command *stubJournaldCommand
wantedOutput []byte
wantErr bool
}{
"success": {
command: &stubJournaldCommand{},
},
"execution failed": {
command: &stubJournaldCommand{outputError: someError},
wantErr: true,
},
"exit error": {
command: &stubJournaldCommand{outputError: &exec.ExitError{}},
wantErr: true,
},
"output check": {
command: &stubJournaldCommand{outputReturn: []byte("asdf")},
wantedOutput: []byte("asdf"),
},
}
for name, tc := range testCases {
t.Run(name, func(t *testing.T) {
assert := assert.New(t)
collector := Collector{cmd: tc.command}
out, err := collector.Collect()
if tc.wantErr {
assert.Error(err)
}
assert.Equal(out, tc.wantedOutput)
})
}
}

View File

@ -13,7 +13,6 @@ go_library(
deps = [
"//bootstrapper/internal/kubernetes/k8sapi",
"//bootstrapper/internal/kubernetes/kubewaiter",
"//internal/attestation/measurements",
"//internal/cloud/azureshared",
"//internal/cloud/cloudprovider",
"//internal/cloud/gcpshared",

View File

@ -20,7 +20,6 @@ import (
"github.com/edgelesssys/constellation/v2/bootstrapper/internal/kubernetes/k8sapi"
"github.com/edgelesssys/constellation/v2/bootstrapper/internal/kubernetes/kubewaiter"
"github.com/edgelesssys/constellation/v2/internal/attestation/measurements"
"github.com/edgelesssys/constellation/v2/internal/cloud/azureshared"
"github.com/edgelesssys/constellation/v2/internal/cloud/cloudprovider"
"github.com/edgelesssys/constellation/v2/internal/cloud/gcpshared"
@ -58,13 +57,12 @@ type KubeWrapper struct {
configProvider configurationProvider
client k8sapi.Client
providerMetadata ProviderMetadata
initialMeasurements measurements.M
getIPAddr func() (string, error)
}
// New creates a new KubeWrapper with real values.
func New(cloudProvider string, clusterUtil clusterUtil, configProvider configurationProvider, client k8sapi.Client,
providerMetadata ProviderMetadata, measurements measurements.M, helmClient helmClient, kubeAPIWaiter kubeAPIWaiter,
providerMetadata ProviderMetadata, helmClient helmClient, kubeAPIWaiter kubeAPIWaiter,
) *KubeWrapper {
return &KubeWrapper{
cloudProvider: cloudProvider,
@ -74,14 +72,13 @@ func New(cloudProvider string, clusterUtil clusterUtil, configProvider configura
configProvider: configProvider,
client: client,
providerMetadata: providerMetadata,
initialMeasurements: measurements,
getIPAddr: getIPAddr,
}
}
// InitCluster initializes a new Kubernetes cluster and applies pod network provider.
func (k *KubeWrapper) InitCluster(
ctx context.Context, cloudServiceAccountURI, versionString, clusterName string, measurementSalt []byte, enforcedPCRs []uint32,
ctx context.Context, cloudServiceAccountURI, versionString, clusterName string, measurementSalt []byte,
helmReleasesRaw []byte, conformanceMode bool, kubernetesComponents components.Components, log *logger.Logger,
) ([]byte, error) {
log.With(zap.String("version", versionString)).Infof("Installing Kubernetes components")
@ -217,15 +214,7 @@ func (k *KubeWrapper) InitCluster(
} else {
controlPlaneIP = controlPlaneEndpoint
}
if err := k.initialMeasurements.SetEnforced(enforcedPCRs); err != nil {
return nil, err
}
measurementsJSON, err := json.Marshal(k.initialMeasurements)
if err != nil {
return nil, fmt.Errorf("marshaling initial measurements: %w", err)
}
serviceConfig := constellationServicesConfig{
initialMeasurementsJSON: measurementsJSON,
measurementSalt: measurementSalt,
subnetworkPodCIDR: subnetworkPodCIDR,
cloudServiceAccountURI: cloudServiceAccountURI,
@ -420,7 +409,6 @@ func getIPAddr() (string, error) {
func (k *KubeWrapper) setupExtraVals(ctx context.Context, serviceConfig constellationServicesConfig) (map[string]any, error) {
extraVals := map[string]any{
"join-service": map[string]any{
"measurements": string(serviceConfig.initialMeasurementsJSON),
"measurementSalt": base64.StdEncoding.EncodeToString(serviceConfig.measurementSalt),
},
"ccm": map[string]any{},
@ -541,7 +529,6 @@ type ccmConfigGetter interface {
}
type constellationServicesConfig struct {
initialMeasurementsJSON []byte
measurementSalt []byte
subnetworkPodCIDR string
cloudServiceAccountURI string

View File

@ -216,7 +216,7 @@ func TestInitCluster(t *testing.T) {
_, err := kube.InitCluster(
context.Background(), serviceAccountURI, string(tc.k8sVersion), "kubernetes",
nil, nil, []byte("{}"), false, nil, logger.NewTest(t),
nil, []byte("{}"), false, nil, logger.NewTest(t),
)
if tc.wantErr {

View File

@ -33,7 +33,7 @@ go_library(
"//internal/constants",
"//internal/kubernetes",
"//internal/kubernetes/kubectl",
"//internal/oid",
"//internal/variant",
"//internal/versions",
"//internal/versions/components",
"//internal/versionsapi",
@ -83,7 +83,7 @@ go_test(
"//internal/config",
"//internal/constants",
"//internal/logger",
"//internal/oid",
"//internal/variant",
"//internal/versions",
"//internal/versions/components",
"//operators/constellation-node-operator/api/v1alpha1",

View File

@ -31,6 +31,7 @@ import (
"github.com/edgelesssys/constellation/v2/internal/cloud/cloudprovider"
"github.com/edgelesssys/constellation/v2/internal/config"
"github.com/edgelesssys/constellation/v2/internal/constants"
"github.com/edgelesssys/constellation/v2/internal/variant"
)
// Creator creates cloud resources.
@ -205,12 +206,17 @@ func (c *Creator) createAzure(ctx context.Context, cl terraformClient, config *c
InstanceType: insType,
StateDiskType: config.Provider.Azure.StateDiskType,
ImageID: image,
ConfidentialVM: *config.Provider.Azure.ConfidentialVM,
SecureBoot: *config.Provider.Azure.SecureBoot,
CreateMAA: config.Provider.Azure.EnforceIDKeyDigest == idkeydigest.MAAFallback,
Debug: config.IsDebugCluster(),
}
attestVariant, err := variant.FromString(config.AttestationVariant)
if err != nil {
return clusterid.File{}, fmt.Errorf("parsing attestation variant: %w", err)
}
vars.ConfidentialVM = attestVariant.Equal(variant.AzureSEVSNP{})
vars = normalizeAzureURIs(vars)
if err := cl.PrepareWorkspace(path.Join("terraform", strings.ToLower(cloudprovider.Azure.String())), &vars); err != nil {

View File

@ -16,6 +16,7 @@ import (
"github.com/edgelesssys/constellation/v2/cli/internal/terraform"
"github.com/edgelesssys/constellation/v2/internal/cloud/cloudprovider"
"github.com/edgelesssys/constellation/v2/internal/config"
"github.com/edgelesssys/constellation/v2/internal/variant"
"github.com/stretchr/testify/assert"
)
@ -57,27 +58,53 @@ func TestCreator(t *testing.T) {
"azure": {
tfClient: &stubTerraformClient{ip: ip},
provider: cloudprovider.Azure,
config: config.Default(),
config: func() *config.Config {
cfg := config.Default()
cfg.AttestationVariant = variant.AzureSEVSNP{}.String()
return cfg
}(),
policyPatcher: &stubPolicyPatcher{},
},
"azure trusted launch": {
tfClient: &stubTerraformClient{ip: ip},
provider: cloudprovider.Azure,
config: func() *config.Config {
cfg := config.Default()
cfg.AttestationVariant = variant.AzureTrustedLaunch{}.String()
return cfg
}(),
policyPatcher: &stubPolicyPatcher{},
},
"azure new policy patch error": {
tfClient: &stubTerraformClient{ip: ip},
provider: cloudprovider.Azure,
config: config.Default(),
config: func() *config.Config {
cfg := config.Default()
cfg.AttestationVariant = variant.AzureSEVSNP{}.String()
return cfg
}(),
policyPatcher: &stubPolicyPatcher{someErr},
wantErr: true,
},
"azure newTerraformClient error": {
newTfClientErr: someErr,
provider: cloudprovider.Azure,
config: config.Default(),
config: func() *config.Config {
cfg := config.Default()
cfg.AttestationVariant = variant.AzureSEVSNP{}.String()
return cfg
}(),
policyPatcher: &stubPolicyPatcher{},
wantErr: true,
},
"azure create cluster error": {
tfClient: &stubTerraformClient{createClusterErr: someErr},
provider: cloudprovider.Azure,
config: config.Default(),
config: func() *config.Config {
cfg := config.Default()
cfg.AttestationVariant = variant.AzureSEVSNP{}.String()
return cfg
}(),
policyPatcher: &stubPolicyPatcher{},
wantErr: true,
wantRollback: true,

View File

@ -18,13 +18,13 @@ import (
"github.com/edgelesssys/constellation/v2/internal/attestation/idkeydigest"
"github.com/edgelesssys/constellation/v2/internal/attestation/measurements"
"github.com/edgelesssys/constellation/v2/internal/config"
"github.com/edgelesssys/constellation/v2/internal/oid"
"github.com/edgelesssys/constellation/v2/internal/variant"
"github.com/spf13/cobra"
)
// Validator validates Platform Configuration Registers (PCRs).
type Validator struct {
attestationVariant oid.Getter
attestationVariant variant.Variant
pcrs measurements.M
idKeyConfig idkeydigest.Config
validator atls.Validator
@ -34,17 +34,17 @@ type Validator struct {
// NewValidator creates a new Validator.
func NewValidator(conf *config.Config, maaURL string, log debugLog) (*Validator, error) {
v := Validator{log: log}
variant, err := oid.FromString(conf.AttestationVariant)
attestVariant, err := variant.FromString(conf.AttestationVariant)
if err != nil {
return nil, fmt.Errorf("parsing attestation variant: %w", err)
}
v.attestationVariant = variant // valid variant
v.attestationVariant = attestVariant // valid variant
if err := v.setPCRs(conf); err != nil {
return nil, err
}
if v.attestationVariant.OID().Equal(oid.AzureSEVSNP{}.OID()) {
if v.attestationVariant.Equal(variant.AzureSEVSNP{}) {
v.idKeyConfig = idkeydigest.Config{
IDKeyDigests: conf.Provider.Azure.IDKeyDigest,
EnforcementPolicy: conf.IDKeyDigestPolicy(),
@ -96,32 +96,11 @@ func (v *Validator) updatePCR(pcrIndex uint32, encoded string) error {
}
func (v *Validator) setPCRs(config *config.Config) error {
switch v.attestationVariant {
case oid.AWSNitroTPM{}:
awsPCRs := config.Provider.AWS.Measurements
if len(awsPCRs) == 0 {
return errors.New("no expected measurement provided")
}
v.pcrs = awsPCRs
case oid.AzureSEVSNP{}, oid.AzureTrustedLaunch{}:
azurePCRs := config.Provider.Azure.Measurements
if len(azurePCRs) == 0 {
return errors.New("no expected measurement provided")
}
v.pcrs = azurePCRs
case oid.GCPSEVES{}:
gcpPCRs := config.Provider.GCP.Measurements
if len(gcpPCRs) == 0 {
return errors.New("no expected measurement provided")
}
v.pcrs = gcpPCRs
case oid.QEMUVTPM{}:
qemuPCRs := config.Provider.QEMU.Measurements
if len(qemuPCRs) == 0 {
return errors.New("no expected measurement provided")
}
v.pcrs = qemuPCRs
measurements := config.GetMeasurements()
if len(measurements) == 0 {
return errors.New("no measurements found in config")
}
v.pcrs = measurements
return nil
}

View File

@ -21,7 +21,7 @@ import (
"github.com/edgelesssys/constellation/v2/internal/attestation/qemu"
"github.com/edgelesssys/constellation/v2/internal/config"
"github.com/edgelesssys/constellation/v2/internal/logger"
"github.com/edgelesssys/constellation/v2/internal/oid"
"github.com/edgelesssys/constellation/v2/internal/variant"
"github.com/spf13/cobra"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
@ -43,7 +43,7 @@ func TestNewValidator(t *testing.T) {
}{
"gcp": {
config: &config.Config{
AttestationVariant: oid.GCPSEVES{}.String(),
AttestationVariant: variant.GCPSEVES{}.String(),
Provider: config.ProviderConfig{
GCP: &config.GCPConfig{
Measurements: testPCRs,
@ -53,7 +53,7 @@ func TestNewValidator(t *testing.T) {
},
"azure cvm": {
config: &config.Config{
AttestationVariant: oid.AzureSEVSNP{}.String(),
AttestationVariant: variant.AzureSEVSNP{}.String(),
Provider: config.ProviderConfig{
Azure: &config.AzureConfig{
Measurements: testPCRs,
@ -63,7 +63,7 @@ func TestNewValidator(t *testing.T) {
},
"azure trusted launch": {
config: &config.Config{
AttestationVariant: oid.AzureTrustedLaunch{}.String(),
AttestationVariant: variant.AzureTrustedLaunch{}.String(),
Provider: config.ProviderConfig{
Azure: &config.AzureConfig{
Measurements: testPCRs,
@ -73,7 +73,7 @@ func TestNewValidator(t *testing.T) {
},
"qemu": {
config: &config.Config{
AttestationVariant: oid.QEMUVTPM{}.String(),
AttestationVariant: variant.QEMUVTPM{}.String(),
Provider: config.ProviderConfig{
QEMU: &config.QEMUConfig{
Measurements: testPCRs,
@ -83,7 +83,7 @@ func TestNewValidator(t *testing.T) {
},
"no pcrs provided": {
config: &config.Config{
AttestationVariant: oid.AzureSEVSNP{}.String(),
AttestationVariant: variant.AzureSEVSNP{}.String(),
Provider: config.ProviderConfig{
Azure: &config.AzureConfig{
Measurements: measurements.M{},
@ -105,7 +105,7 @@ func TestNewValidator(t *testing.T) {
},
"set idkeydigest": {
config: &config.Config{
AttestationVariant: oid.AzureSEVSNP{}.String(),
AttestationVariant: variant.AzureSEVSNP{}.String(),
Provider: config.ProviderConfig{
Azure: &config.AzureConfig{
Measurements: testPCRs,
@ -128,7 +128,7 @@ func TestNewValidator(t *testing.T) {
} else {
assert.NoError(err)
assert.Equal(tc.config.GetMeasurements(), validators.pcrs)
variant, err := oid.FromString(tc.config.AttestationVariant)
variant, err := variant.FromString(tc.config.AttestationVariant)
require.NoError(t, err)
assert.Equal(variant, validators.attestationVariant)
}
@ -156,17 +156,17 @@ func TestValidatorV(t *testing.T) {
}
testCases := map[string]struct {
variant oid.Getter
variant variant.Variant
pcrs measurements.M
wantVs atls.Validator
}{
"gcp": {
variant: oid.GCPSEVES{},
variant: variant.GCPSEVES{},
pcrs: newTestPCRs(),
wantVs: gcp.NewValidator(newTestPCRs(), nil),
},
"azure cvm": {
variant: oid.AzureSEVSNP{},
variant: variant.AzureSEVSNP{},
pcrs: newTestPCRs(),
wantVs: snp.NewValidator(
newTestPCRs(),
@ -175,12 +175,12 @@ func TestValidatorV(t *testing.T) {
),
},
"azure trusted launch": {
variant: oid.AzureTrustedLaunch{},
variant: variant.AzureTrustedLaunch{},
pcrs: newTestPCRs(),
wantVs: trustedlaunch.NewValidator(newTestPCRs(), nil),
},
"qemu": {
variant: oid.QEMUVTPM{},
variant: variant.QEMUVTPM{},
pcrs: newTestPCRs(),
wantVs: qemu.NewValidator(newTestPCRs(), nil),
},
@ -235,50 +235,50 @@ func TestValidatorUpdateInitPCRs(t *testing.T) {
}
testCases := map[string]struct {
variant oid.Getter
variant variant.Variant
pcrs measurements.M
ownerID string
clusterID string
wantErr bool
}{
"gcp update owner ID": {
variant: oid.GCPSEVES{},
variant: variant.GCPSEVES{},
pcrs: newTestPCRs(),
ownerID: one64,
},
"gcp update cluster ID": {
variant: oid.GCPSEVES{},
variant: variant.GCPSEVES{},
pcrs: newTestPCRs(),
clusterID: one64,
},
"gcp update both": {
variant: oid.GCPSEVES{},
variant: variant.GCPSEVES{},
pcrs: newTestPCRs(),
ownerID: one64,
clusterID: one64,
},
"azure update owner ID": {
variant: oid.AzureSEVSNP{},
variant: variant.AzureSEVSNP{},
pcrs: newTestPCRs(),
ownerID: one64,
},
"azure update cluster ID": {
variant: oid.AzureSEVSNP{},
variant: variant.AzureSEVSNP{},
pcrs: newTestPCRs(),
clusterID: one64,
},
"azure update both": {
variant: oid.AzureSEVSNP{},
variant: variant.AzureSEVSNP{},
pcrs: newTestPCRs(),
ownerID: one64,
clusterID: one64,
},
"owner ID and cluster ID empty": {
variant: oid.GCPSEVES{},
variant: variant.GCPSEVES{},
pcrs: newTestPCRs(),
},
"invalid encoding": {
variant: oid.GCPSEVES{},
variant: variant.GCPSEVES{},
pcrs: newTestPCRs(),
ownerID: "invalid",
wantErr: true,
@ -421,7 +421,7 @@ func TestUpdatePCR(t *testing.T) {
}
validators := &Validator{
attestationVariant: oid.GCPSEVES{},
attestationVariant: variant.GCPSEVES{},
pcrs: pcrs,
}
err := validators.updatePCR(tc.pcrIndex, tc.encoded)

View File

@ -61,9 +61,9 @@ go_library(
"//internal/kubernetes/kubectl",
"//internal/license",
"//internal/logger",
"//internal/oid",
"//internal/retry",
"//internal/sigstore",
"//internal/variant",
"//internal/versions",
"//internal/versionsapi",
"//internal/versionsapi/fetcher",
@ -127,7 +127,7 @@ go_test(
"//internal/kms/uri",
"//internal/license",
"//internal/logger",
"//internal/oid",
"//internal/variant",
"//internal/versions",
"//internal/versionsapi",
"//verify/verifyproto",

View File

@ -15,7 +15,7 @@ import (
"github.com/edgelesssys/constellation/v2/internal/config"
"github.com/edgelesssys/constellation/v2/internal/constants"
"github.com/edgelesssys/constellation/v2/internal/file"
"github.com/edgelesssys/constellation/v2/internal/oid"
"github.com/edgelesssys/constellation/v2/internal/variant"
"github.com/edgelesssys/constellation/v2/internal/versions"
"github.com/siderolabs/talos/pkg/machinery/config/encoder"
"github.com/spf13/afero"
@ -109,13 +109,13 @@ func createConfig(provider cloudprovider.Provider) *config.Config {
// TODO(AB#2976): Replace hardcoded values with user input
switch provider {
case cloudprovider.AWS:
conf.AttestationVariant = oid.AWSNitroTPM{}.String()
conf.AttestationVariant = variant.AWSNitroTPM{}.String()
case cloudprovider.Azure:
conf.AttestationVariant = oid.AzureSEVSNP{}.String()
conf.AttestationVariant = variant.AzureSEVSNP{}.String()
case cloudprovider.GCP:
conf.AttestationVariant = oid.GCPSEVES{}.String()
conf.AttestationVariant = variant.GCPSEVES{}.String()
case cloudprovider.QEMU:
conf.AttestationVariant = oid.QEMUVTPM{}.String()
conf.AttestationVariant = variant.QEMUVTPM{}.String()
}
return conf

View File

@ -15,7 +15,7 @@ import (
"github.com/edgelesssys/constellation/v2/internal/constants"
"github.com/edgelesssys/constellation/v2/internal/file"
"github.com/edgelesssys/constellation/v2/internal/logger"
"github.com/edgelesssys/constellation/v2/internal/oid"
"github.com/edgelesssys/constellation/v2/internal/variant"
"github.com/edgelesssys/constellation/v2/internal/versions"
"github.com/spf13/afero"
"github.com/stretchr/testify/assert"
@ -94,7 +94,7 @@ func TestConfigGenerateDefaultGCPSpecific(t *testing.T) {
require.NoError(cg.configGenerate(cmd, fileHandler, cloudprovider.GCP))
// TODO(AB#2976): Remove this once attestation variants are dynamically created
wantConf.AttestationVariant = oid.GCPSEVES{}.String()
wantConf.AttestationVariant = variant.GCPSEVES{}.String()
var readConfig config.Config
err := fileHandler.ReadYAML(constants.ConfigFilename, &readConfig)

View File

@ -18,6 +18,7 @@ import (
"github.com/edgelesssys/constellation/v2/internal/config"
"github.com/edgelesssys/constellation/v2/internal/constants"
"github.com/edgelesssys/constellation/v2/internal/file"
"github.com/edgelesssys/constellation/v2/internal/variant"
"github.com/spf13/afero"
"github.com/spf13/cobra"
)
@ -95,7 +96,12 @@ func (c *createCmd) create(cmd *cobra.Command, creator cloudCreator, fileHandler
printedAWarning = true
}
if conf.IsAzureNonCVM() {
attestVariant, err := variant.FromString(conf.AttestationVariant)
if err != nil {
return fmt.Errorf("parsing attestation variant: %w", err)
}
if attestVariant.Equal(variant.AzureTrustedLaunch{}) {
cmd.PrintErrln("Disabling Confidential VMs is insecure. Use only for evaluation purposes.")
printedAWarning = true
if conf.IDKeyDigestPolicy() == idkeydigest.StrictChecking || conf.IDKeyDigestPolicy() == idkeydigest.MAAFallback {

View File

@ -173,7 +173,6 @@ func (i *initCmd) initialize(cmd *cobra.Command, newDialer func(validator *cloud
KubernetesVersion: versions.VersionConfigs[k8sVersion].ClusterVersion,
KubernetesComponents: versions.VersionConfigs[k8sVersion].KubernetesComponents.ToInitProto(),
HelmDeployments: helmDeployments,
EnforcedPcrs: conf.EnforcedPCRs(),
ConformanceMode: flags.conformance,
InitSecret: idFile.InitSecret,
ClusterName: clusterName,

View File

@ -33,7 +33,7 @@ import (
"github.com/edgelesssys/constellation/v2/internal/kms/uri"
"github.com/edgelesssys/constellation/v2/internal/license"
"github.com/edgelesssys/constellation/v2/internal/logger"
"github.com/edgelesssys/constellation/v2/internal/oid"
"github.com/edgelesssys/constellation/v2/internal/variant"
"github.com/edgelesssys/constellation/v2/internal/versions"
"github.com/spf13/afero"
"github.com/stretchr/testify/assert"
@ -399,14 +399,14 @@ func TestAttestation(t *testing.T) {
netDialer := testdialer.NewBufconnDialer()
newDialer := func(v *cloudcmd.Validator) *dialer.Dialer {
validator := &testValidator{
Getter: oid.QEMUVTPM{},
Getter: variant.QEMUVTPM{},
pcrs: v.PCRS(),
}
return dialer.New(nil, validator, netDialer)
}
issuer := &testIssuer{
Getter: oid.QEMUVTPM{},
Getter: variant.QEMUVTPM{},
pcrs: map[uint32][]byte{
0: bytes.Repeat([]byte{0xFF}, 32),
1: bytes.Repeat([]byte{0xFF}, 32),
@ -436,7 +436,7 @@ func TestAttestation(t *testing.T) {
cfg := config.Default()
cfg.Image = "image"
cfg.AttestationVariant = oid.QEMUVTPM{}.String()
cfg.AttestationVariant = variant.QEMUVTPM{}.String()
cfg.RemoveProviderExcept(cloudprovider.QEMU)
cfg.Provider.QEMU.Measurements[0] = measurements.WithAllBytes(0x00, measurements.Enforce)
cfg.Provider.QEMU.Measurements[1] = measurements.WithAllBytes(0x11, measurements.Enforce)
@ -460,11 +460,11 @@ func TestAttestation(t *testing.T) {
}
type testValidator struct {
oid.Getter
variant.Getter
pcrs measurements.M
}
func (v *testValidator) Validate(attDoc []byte, _ []byte) ([]byte, error) {
func (v *testValidator) Validate(_ context.Context, attDoc []byte, _ []byte) ([]byte, error) {
var attestation struct {
UserData []byte
PCRs map[uint32][]byte
@ -482,11 +482,11 @@ func (v *testValidator) Validate(attDoc []byte, _ []byte) ([]byte, error) {
}
type testIssuer struct {
oid.Getter
variant.Getter
pcrs map[uint32][]byte
}
func (i *testIssuer) Issue(userData []byte, _ []byte) ([]byte, error) {
func (i *testIssuer) Issue(_ context.Context, userData []byte, _ []byte) ([]byte, error) {
return json.Marshal(
struct {
UserData []byte
@ -530,7 +530,7 @@ func defaultConfigWithExpectedMeasurements(t *testing.T, conf *config.Config, cs
switch csp {
case cloudprovider.Azure:
conf.AttestationVariant = oid.AzureSEVSNP{}.String()
conf.AttestationVariant = variant.AzureSEVSNP{}.String()
conf.Provider.Azure.SubscriptionID = "01234567-0123-0123-0123-0123456789ab"
conf.Provider.Azure.TenantID = "01234567-0123-0123-0123-0123456789ab"
conf.Provider.Azure.Location = "test-location"
@ -542,7 +542,7 @@ func defaultConfigWithExpectedMeasurements(t *testing.T, conf *config.Config, cs
conf.Provider.Azure.Measurements[9] = measurements.WithAllBytes(0x11, measurements.Enforce)
conf.Provider.Azure.Measurements[12] = measurements.WithAllBytes(0xcc, measurements.Enforce)
case cloudprovider.GCP:
conf.AttestationVariant = oid.GCPSEVES{}.String()
conf.AttestationVariant = variant.GCPSEVES{}.String()
conf.Provider.GCP.Region = "test-region"
conf.Provider.GCP.Project = "test-project"
conf.Provider.GCP.Zone = "test-zone"
@ -551,7 +551,7 @@ func defaultConfigWithExpectedMeasurements(t *testing.T, conf *config.Config, cs
conf.Provider.GCP.Measurements[9] = measurements.WithAllBytes(0x11, measurements.Enforce)
conf.Provider.GCP.Measurements[12] = measurements.WithAllBytes(0xcc, measurements.Enforce)
case cloudprovider.QEMU:
conf.AttestationVariant = oid.QEMUVTPM{}.String()
conf.AttestationVariant = variant.QEMUVTPM{}.String()
conf.Provider.QEMU.Measurements[4] = measurements.WithAllBytes(0x44, measurements.Enforce)
conf.Provider.QEMU.Measurements[9] = measurements.WithAllBytes(0x11, measurements.Enforce)
conf.Provider.QEMU.Measurements[12] = measurements.WithAllBytes(0xcc, measurements.Enforce)

View File

@ -232,7 +232,7 @@ func (v *constellationVerifier) Verify(
}
v.log.Debugf("Verifying attestation")
signedData, err := validator.Validate(resp.Attestation, req.Nonce)
signedData, err := validator.Validate(ctx, resp.Attestation, req.Nonce)
if err != nil {
return fmt.Errorf("validating attestation: %w", err)
}

View File

@ -25,7 +25,7 @@ import (
"github.com/edgelesssys/constellation/v2/internal/grpc/dialer"
"github.com/edgelesssys/constellation/v2/internal/grpc/testdialer"
"github.com/edgelesssys/constellation/v2/internal/logger"
"github.com/edgelesssys/constellation/v2/internal/oid"
"github.com/edgelesssys/constellation/v2/internal/variant"
"github.com/edgelesssys/constellation/v2/verify/verifyproto"
"github.com/spf13/afero"
"github.com/stretchr/testify/assert"
@ -247,7 +247,7 @@ func TestVerifyClient(t *testing.T) {
Nonce: tc.nonce,
}
err = verifier.Verify(context.Background(), addr, request, atls.NewFakeValidator(oid.Dummy{}))
err = verifier.Verify(context.Background(), addr, request, atls.NewFakeValidator(variant.Dummy{}))
if tc.wantErr {
assert.Error(err)

View File

@ -362,7 +362,7 @@ go_test(
"//internal/deploy/helm",
"//internal/file",
"//internal/logger",
"//internal/oid",
"//internal/variant",
"@com_github_pkg_errors//:errors",
"@com_github_spf13_afero//:afero",
"@com_github_stretchr_testify//assert",

View File

@ -481,6 +481,14 @@ func extendConstellationServicesValues(
}
joinServiceVals["attestationVariant"] = config.AttestationVariant
// measurements are updated separately during upgrade,
// so we only set them in Helm during init.
measurementsJSON, err := json.Marshal(config.GetMeasurements())
if err != nil {
return fmt.Errorf("marshalling measurements: %w", err)
}
joinServiceVals["measurements"] = string(measurementsJSON)
verifyServiceVals, ok := in["verification-service"].(map[string]any)
if !ok {
return errors.New("invalid verification-service values")

View File

@ -23,7 +23,7 @@ import (
"github.com/edgelesssys/constellation/v2/internal/cloud/cloudprovider"
"github.com/edgelesssys/constellation/v2/internal/config"
"github.com/edgelesssys/constellation/v2/internal/deploy/helm"
"github.com/edgelesssys/constellation/v2/internal/oid"
"github.com/edgelesssys/constellation/v2/internal/variant"
"github.com/pkg/errors"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
@ -62,7 +62,7 @@ func TestConstellationServices(t *testing.T) {
}{
"AWS": {
config: &config.Config{
AttestationVariant: oid.AWSNitroTPM{}.String(),
AttestationVariant: variant.AWSNitroTPM{}.String(),
Provider: config.ProviderConfig{AWS: &config.AWSConfig{}},
},
valuesModifier: prepareAWSValues,
@ -70,7 +70,7 @@ func TestConstellationServices(t *testing.T) {
},
"Azure": {
config: &config.Config{
AttestationVariant: oid.AzureSEVSNP{}.String(),
AttestationVariant: variant.AzureSEVSNP{}.String(),
Provider: config.ProviderConfig{Azure: &config.AzureConfig{
DeployCSIDriver: toPtr(true),
EnforceIDKeyDigest: idkeydigest.StrictChecking,
@ -87,7 +87,7 @@ func TestConstellationServices(t *testing.T) {
},
"GCP": {
config: &config.Config{
AttestationVariant: oid.GCPSEVES{}.String(),
AttestationVariant: variant.GCPSEVES{}.String(),
Provider: config.ProviderConfig{GCP: &config.GCPConfig{
DeployCSIDriver: toPtr(true),
}},
@ -97,7 +97,7 @@ func TestConstellationServices(t *testing.T) {
},
"OpenStack": {
config: &config.Config{
AttestationVariant: oid.Dummy{}.String(),
AttestationVariant: variant.Dummy{}.String(),
Provider: config.ProviderConfig{OpenStack: &config.OpenStackConfig{}},
},
valuesModifier: prepareOpenStackValues,
@ -105,7 +105,7 @@ func TestConstellationServices(t *testing.T) {
},
"QEMU": {
config: &config.Config{
AttestationVariant: oid.QEMUVTPM{}.String(),
AttestationVariant: variant.QEMUVTPM{}.String(),
Provider: config.ProviderConfig{QEMU: &config.QEMUConfig{}},
},
valuesModifier: prepareQEMUValues,

View File

@ -12,6 +12,7 @@ go_library(
deps = [
"//internal/cloud/cloudprovider",
"//internal/config",
"//internal/variant",
"//internal/versionsapi",
"//internal/versionsapi/fetcher",
"@com_github_schollz_progressbar_v3//:progressbar",
@ -30,6 +31,7 @@ go_test(
"//internal/cloud/cloudprovider",
"//internal/config",
"//internal/file",
"//internal/variant",
"//internal/versionsapi",
"@com_github_spf13_afero//:afero",
"@com_github_stretchr_testify//assert",

View File

@ -21,6 +21,7 @@ import (
"github.com/edgelesssys/constellation/v2/internal/cloud/cloudprovider"
"github.com/edgelesssys/constellation/v2/internal/config"
"github.com/edgelesssys/constellation/v2/internal/variant"
"github.com/edgelesssys/constellation/v2/internal/versionsapi"
"github.com/edgelesssys/constellation/v2/internal/versionsapi/fetcher"
"github.com/spf13/afero"
@ -43,7 +44,7 @@ func New() *Fetcher {
// FetchReference fetches the image reference for a given image version uid, CSP and image variant.
func (f *Fetcher) FetchReference(ctx context.Context, config *config.Config) (string, error) {
provider := config.GetProvider()
variant, err := variant(provider, config)
variant, err := imageVariant(provider, config)
if err != nil {
return "", fmt.Errorf("determining variant: %w", err)
}
@ -85,16 +86,20 @@ func (f *Fetcher) FetchReference(ctx context.Context, config *config.Config) (st
return getReferenceFromImageInfo(provider, variant, imgInfo)
}
// variant returns the image variant for a given CSP and configuration.
func variant(provider cloudprovider.Provider, config *config.Config) (string, error) {
// imageVariant returns the image variant for a given CSP and configuration.
func imageVariant(provider cloudprovider.Provider, config *config.Config) (string, error) {
switch provider {
case cloudprovider.AWS:
return config.Provider.AWS.Region, nil
case cloudprovider.Azure:
if *config.Provider.Azure.ConfidentialVM {
return "cvm", nil
attestVariant, err := variant.FromString(config.AttestationVariant)
if err != nil {
return "", fmt.Errorf("parsing attestation variant: %w", err)
}
if attestVariant.Equal(variant.AzureTrustedLaunch{}) {
return "trustedlaunch", nil
}
return "cvm", nil
case cloudprovider.GCP:
return "sev-es", nil

View File

@ -16,6 +16,7 @@ import (
"github.com/edgelesssys/constellation/v2/internal/cloud/cloudprovider"
"github.com/edgelesssys/constellation/v2/internal/config"
"github.com/edgelesssys/constellation/v2/internal/file"
"github.com/edgelesssys/constellation/v2/internal/variant"
"github.com/edgelesssys/constellation/v2/internal/versionsapi"
"github.com/spf13/afero"
"github.com/stretchr/testify/assert"
@ -108,7 +109,7 @@ func TestGetReference(t *testing.T) {
}
}
func TestVariant(t *testing.T) {
func TestImageVariant(t *testing.T) {
testCases := map[string]struct {
csp cloudprovider.Provider
config *config.Config
@ -125,18 +126,16 @@ func TestVariant(t *testing.T) {
"Azure cvm": {
csp: cloudprovider.Azure,
config: &config.Config{
Image: "someImage", Provider: config.ProviderConfig{
Azure: &config.AzureConfig{ConfidentialVM: func() *bool { b := true; return &b }()},
},
AttestationVariant: variant.AzureSEVSNP{}.String(),
Image: "someImage", Provider: config.ProviderConfig{Azure: &config.AzureConfig{}},
},
wantVariant: "cvm",
},
"Azure trustedlaunch": {
csp: cloudprovider.Azure,
config: &config.Config{
Image: "someImage", Provider: config.ProviderConfig{
Azure: &config.AzureConfig{ConfidentialVM: func() *bool { b := false; return &b }()},
},
AttestationVariant: variant.AzureTrustedLaunch{}.String(),
Image: "someImage", Provider: config.ProviderConfig{Azure: &config.AzureConfig{}},
},
wantVariant: "trustedlaunch",
},
@ -172,7 +171,7 @@ func TestVariant(t *testing.T) {
assert := assert.New(t)
require := require.New(t)
vari, err := variant(tc.csp, tc.config)
vari, err := imageVariant(tc.csp, tc.config)
if tc.wantErr {
assert.Error(err)
return

View File

@ -24,8 +24,8 @@ go_library(
"//internal/grpc/dialer",
"//internal/kms/setup",
"//internal/logger",
"//internal/oid",
"//internal/role",
"//internal/variant",
"@com_github_spf13_afero//:afero",
"@org_uber_go_zap//:zap",
],

View File

@ -30,8 +30,8 @@ import (
"github.com/edgelesssys/constellation/v2/internal/grpc/dialer"
kmssetup "github.com/edgelesssys/constellation/v2/internal/kms/setup"
"github.com/edgelesssys/constellation/v2/internal/logger"
"github.com/edgelesssys/constellation/v2/internal/oid"
"github.com/edgelesssys/constellation/v2/internal/role"
"github.com/edgelesssys/constellation/v2/internal/variant"
"github.com/spf13/afero"
"go.uber.org/zap"
)
@ -54,7 +54,7 @@ func main() {
Infof("Starting disk-mapper")
// set up quote issuer for aTLS connections
attestVariant, err := oid.FromString(os.Getenv(constants.AttestationVariant))
attestVariant, err := variant.FromString(os.Getenv(constants.AttestationVariant))
if err != nil {
log.With(zap.Error(err)).Fatalf("Failed to parse attestation variant")
}

View File

@ -32,7 +32,7 @@ go_test(
"//internal/grpc/testdialer",
"//internal/kms/kms",
"//internal/logger",
"//internal/oid",
"//internal/variant",
"@com_github_stretchr_testify//assert",
"@com_github_stretchr_testify//require",
"@org_uber_go_goleak//:goleak",

View File

@ -19,7 +19,7 @@ import (
"github.com/edgelesssys/constellation/v2/internal/grpc/testdialer"
"github.com/edgelesssys/constellation/v2/internal/kms/kms"
"github.com/edgelesssys/constellation/v2/internal/logger"
"github.com/edgelesssys/constellation/v2/internal/oid"
"github.com/edgelesssys/constellation/v2/internal/variant"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"go.uber.org/goleak"
@ -36,7 +36,7 @@ func TestServe(t *testing.T) {
assert := assert.New(t)
log := logger.NewTest(t)
uuid := "uuid"
server := New(atls.NewFakeIssuer(oid.Dummy{}), newStubKMS(nil, nil), log)
server := New(atls.NewFakeIssuer(variant.Dummy{}), newStubKMS(nil, nil), log)
dialer := testdialer.NewBufconnDialer()
listener := dialer.GetListener("192.0.2.1:1234")
ctx, cancel := context.WithCancel(context.Background())
@ -53,7 +53,7 @@ func TestServe(t *testing.T) {
cancel()
wg.Wait()
server = New(atls.NewFakeIssuer(oid.Dummy{}), newStubKMS(nil, nil), log)
server = New(atls.NewFakeIssuer(variant.Dummy{}), newStubKMS(nil, nil), log)
dialer = testdialer.NewBufconnDialer()
listener = dialer.GetListener("192.0.2.1:1234")
@ -105,7 +105,7 @@ func TestRecover(t *testing.T) {
ctx := context.Background()
serverUUID := "uuid"
server := New(atls.NewFakeIssuer(oid.Dummy{}), tc.factory, logger.NewTest(t))
server := New(atls.NewFakeIssuer(variant.Dummy{}), tc.factory, logger.NewTest(t))
netDialer := testdialer.NewBufconnDialer()
listener := netDialer.GetListener("192.0.2.1:1234")

View File

@ -2,12 +2,14 @@
This section aids you in finding problems when working with Constellation.
## Issues with creating new clusters
## Common issues
### Issues with creating new clusters
When you create a new cluster, you should always use the [latest release](https://github.com/edgelesssys/constellation/releases/latest).
If something doesn't work, check out the [known issues](https://github.com/edgelesssys/constellation/issues?q=is%3Aopen+is%3Aissue+label%3A%22known+issue%22).
## Azure: Resource Providers can't be registered
### Azure: Resource Providers can't be registered
On Azure, you may receive the following error when running `create` or `terminate` with limited IAM permissions:
```shell-session
@ -35,11 +37,39 @@ Or alternatively, for `terminate`:
ARM_SKIP_PROVIDER_REGISTRATION=true constellation terminate
```
## Cloud logging
### Nodes fail to join with error `untrusted PCR value`
To provide information during early stages of the node's boot process, Constellation logs messages into the cloud providers' log systems. Since these offerings **aren't** confidential, only generic information without any sensitive values are stored. This provides administrators with a high level understanding of the current state of a node.
This error indicates that a node's [attestation statement](../architecture/attestation.md) contains measurements that don't match the trusted values expected by the [JoinService](../architecture/microservices.md#joinservice).
This may for example happen if the cloud provider updates the VM's firmware such that it influences the [runtime measurements](../architecture/attestation.md#runtime-measurements) in an unforeseen way.
You can change the expected measurements to resolve the failure.
You can view these information in the follow places:
:::caution
Attestation and trusted measurements are crucial for the security of your cluster.
Be extra careful when manually changing these settings.
When in doubt, check if the encountered [issue is known](https://github.com/edgelesssys/constellation/issues?q=is%3Aopen+is%3Aissue+label%3A%22known+issue%22) or [contact support](https://github.com/edgelesssys/constellation#support).
:::
You can use the `upgrade apply` command to change measurements of a running cluster:
1. Modify the `measurements` key in your local `constellation-conf.yaml` to the expected values.
2. Run `constellation upgrade apply`.
Keep in mind that running `upgrade apply` also applies any version changes from your config to the cluster.
You can run these commands to learn about the versions currently configured in the cluster:
- Kubernetes API server version: `kubectl get nodeversion constellation-version -o json -n kube-system | jq .spec.kubernetesClusterVersion`
- image version: `kubectl get nodeversion constellation-version -o json -n kube-system | jq .spec.imageVersion`
- microservices versions: `helm list --filter 'constellation-services' -n kube-system`
## Diagnosing issues
### Cloud logging
To provide information during early stages of a node's boot process, Constellation logs messages to the log systems of the cloud providers. Since these offerings **aren't** confidential, only generic information without any sensitive values is stored. This provides administrators with a high-level understanding of the current state of a node.
You can view this information in the following places:
<tabs groupId="csp">
<tabItem value="azure" label="Azure">
@ -79,7 +109,7 @@ Constellation uses the default bucket to store logs. Its [default retention peri
</tabItem>
</tabs>
## Connect to nodes
### Node shell access
Debugging via a shell on a node is [directly supported by Kubernetes](https://kubernetes.io/docs/tasks/debug/debug-application/debug-running-pod/#node-shell-session).
@ -106,29 +136,3 @@ Debugging via a shell on a node is [directly supported by Kubernetes](https://ku
```sh
kubectl delete pod node-debugger-constell-worker-xksa0-000000-bjthj
```
## Nodes fail to join with error `untrusted PCR value`
This error indicates that a node's [attestation statement](../architecture/attestation.md) contains measurements that don't match the trusted values expected by the [JoinService](../architecture/microservices.md#joinservice).
This may for example happen if the cloud provider updates the VM's firmware such that it influences the [runtime measurements](../architecture/attestation.md#runtime-measurements) in an unforeseen way.
You can change the expected measurements to resolve the failure.
:::caution
Attestation and trusted measurements are crucial for the security of your cluster.
Be extra careful when manually changing these settings.
When in doubt, check if the encountered [issue is known](https://github.com/edgelesssys/constellation/issues?q=is%3Aopen+is%3Aissue+label%3A%22known+issue%22) or [contact support](https://github.com/edgelesssys/constellation#support).
:::
You can use the `upgrade apply` command to change measurements of a running cluster:
1. Modify the `measurements` key in your local `constellation-conf.yaml` to the expected values.
2. Run `constellation upgrade apply`.
Keep in mind that running `upgrade apply` will also apply any version changes you made in your config to the cluster.
You can run these commands to learn about the versions currently configured in the cluster:
- Kubernetes API server version: `kubectl get nodeversion constellation-version -o json -n kube-system | jq .spec.kubernetesClusterVersion`
- image version: `kubectl get nodeversion constellation-version -o json -n kube-system | jq .spec.imageVersion`
- microservices versions: `helm list --filter 'constellation-services' -n kube-system`

View File

@ -8,7 +8,7 @@ Which versions are available depends on the CLI version you are using.
:::caution
Upgrades arent't yet implemented for AWS. If you require this feature, [let us know](https://github.com/edgelesssys/constellation/issues/new?assignees=&labels=&template=feature_request.md)!
Upgrades aren't yet implemented for AWS. If you require this feature, [let us know](https://github.com/edgelesssys/constellation/issues/new?assignees=&labels=&template=feature_request.md)!
:::

2
go.mod
View File

@ -223,7 +223,7 @@ require (
github.com/google/uuid v1.3.0 // indirect
github.com/googleapis/enterprise-certificate-proxy v0.2.3 // indirect
github.com/gophercloud/gophercloud v1.2.0
github.com/gophercloud/utils v0.0.0-20230316075016-e15d7ee3ba3b
github.com/gophercloud/utils v0.0.0-20230324070755-05e9e7f5ea4d
github.com/gorilla/mux v1.8.0 // indirect
github.com/gosuri/uitable v0.0.4 // indirect
github.com/gregjones/httpcache v0.0.0-20190611155906-901d90724c79 // indirect

4
go.sum
View File

@ -740,8 +740,8 @@ github.com/googleapis/google-cloud-go-testing v0.0.0-20200911160855-bcd43fbb19e8
github.com/gophercloud/gophercloud v1.1.1/go.mod h1:aAVqcocTSXh2vYFZ1JTvx4EQmfgzxRcNupUfxZbBNDM=
github.com/gophercloud/gophercloud v1.2.0 h1:1oXyj4g54KBg/kFtCdMM6jtxSzeIyg8wv4z1HoGPp1E=
github.com/gophercloud/gophercloud v1.2.0/go.mod h1:aAVqcocTSXh2vYFZ1JTvx4EQmfgzxRcNupUfxZbBNDM=
github.com/gophercloud/utils v0.0.0-20230316075016-e15d7ee3ba3b h1:g9xk/61NXFpeG7zEReUsv2VeQRux1dXhT/xGHtJD/mA=
github.com/gophercloud/utils v0.0.0-20230316075016-e15d7ee3ba3b/go.mod h1:z4Dey7xsTUXgcB1C8elMvGRKTjV1ez0eoYQlMrduG1g=
github.com/gophercloud/utils v0.0.0-20230324070755-05e9e7f5ea4d h1:AfRlf5NnsYsHIW5nNxhYp+99Bmj/fLeOYwD5Z4CMlzw=
github.com/gophercloud/utils v0.0.0-20230324070755-05e9e7f5ea4d/go.mod h1:z4Dey7xsTUXgcB1C8elMvGRKTjV1ez0eoYQlMrduG1g=
github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY=
github.com/gordonklaus/ineffassign v0.0.0-20200309095847-7953dde2c7bf/go.mod h1:cuNKsD1zp2v6XfE/orVX2QE1LC+i254ceGcVeDT3pTU=
github.com/goreleaser/goreleaser v0.134.0/go.mod h1:ZT6Y2rSYa6NxQzIsdfWWNWAlYGXGbreo66NmE+3X3WQ=

View File

@ -168,7 +168,7 @@ require (
github.com/googleapis/enterprise-certificate-proxy v0.2.3 // indirect
github.com/googleapis/gax-go/v2 v2.7.1 // indirect
github.com/gophercloud/gophercloud v1.2.0 // indirect
github.com/gophercloud/utils v0.0.0-20230316075016-e15d7ee3ba3b // indirect
github.com/gophercloud/utils v0.0.0-20230324070755-05e9e7f5ea4d // indirect
github.com/gorilla/mux v1.8.0 // indirect
github.com/gosuri/uitable v0.0.4 // indirect
github.com/gregjones/httpcache v0.0.0-20190611155906-901d90724c79 // indirect

View File

@ -729,8 +729,8 @@ github.com/googleapis/google-cloud-go-testing v0.0.0-20200911160855-bcd43fbb19e8
github.com/gophercloud/gophercloud v1.1.1/go.mod h1:aAVqcocTSXh2vYFZ1JTvx4EQmfgzxRcNupUfxZbBNDM=
github.com/gophercloud/gophercloud v1.2.0 h1:1oXyj4g54KBg/kFtCdMM6jtxSzeIyg8wv4z1HoGPp1E=
github.com/gophercloud/gophercloud v1.2.0/go.mod h1:aAVqcocTSXh2vYFZ1JTvx4EQmfgzxRcNupUfxZbBNDM=
github.com/gophercloud/utils v0.0.0-20230316075016-e15d7ee3ba3b h1:g9xk/61NXFpeG7zEReUsv2VeQRux1dXhT/xGHtJD/mA=
github.com/gophercloud/utils v0.0.0-20230316075016-e15d7ee3ba3b/go.mod h1:z4Dey7xsTUXgcB1C8elMvGRKTjV1ez0eoYQlMrduG1g=
github.com/gophercloud/utils v0.0.0-20230324070755-05e9e7f5ea4d h1:AfRlf5NnsYsHIW5nNxhYp+99Bmj/fLeOYwD5Z4CMlzw=
github.com/gophercloud/utils v0.0.0-20230324070755-05e9e7f5ea4d/go.mod h1:z4Dey7xsTUXgcB1C8elMvGRKTjV1ez0eoYQlMrduG1g=
github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY=
github.com/gordonklaus/ineffassign v0.0.0-20200309095847-7953dde2c7bf/go.mod h1:cuNKsD1zp2v6XfE/orVX2QE1LC+i254ceGcVeDT3pTU=
github.com/goreleaser/goreleaser v0.134.0/go.mod h1:ZT6Y2rSYa6NxQzIsdfWWNWAlYGXGbreo66NmE+3X3WQ=

View File

@ -1,5 +1,5 @@
# syntax=docker/dockerfile:1.5-labs
FROM alpine:3.17.1@sha256:93d5a28ff72d288d69b5997b8ba47396d2cbb62a72b5d87cd3351094b5d578a0 as builder
FROM alpine:3.17.2@sha256:e2e16842c9b54d985bf1ef9242a313f36b856181f188de21313820e177002501 as builder
#
# Install dependencies

View File

@ -1,5 +1,5 @@
# syntax=docker/dockerfile:1.5-labs
FROM alpine:3.17.1@sha256:93d5a28ff72d288d69b5997b8ba47396d2cbb62a72b5d87cd3351094b5d578a0 as builder
FROM alpine:3.17.2@sha256:e2e16842c9b54d985bf1ef9242a313f36b856181f188de21313820e177002501 as builder
ADD --checksum=sha256:11968a8b706095a081ac30168849b351b0263a6df5c224119aa914d7e5afb0c1 \
https://github.com/reproducible-containers/repro-get/releases/download/v0.3.0/repro-get-v0.3.0.linux-amd64 \

View File

@ -5,7 +5,7 @@ go 1.20
require (
github.com/google/go-licenses v1.6.0
github.com/katexochen/sh/v3 v3.6.0
golang.org/x/vuln v0.0.0-20230322160202-f2d9b5a6e023
golang.org/x/vuln v0.0.0-20230325131008-9550759f8614
)
require (
@ -27,12 +27,12 @@ require (
github.com/xanzy/ssh-agent v0.2.1 // indirect
go.opencensus.io v0.23.0 // indirect
golang.org/x/crypto v0.1.0 // indirect
golang.org/x/mod v0.8.0 // indirect
golang.org/x/net v0.6.0 // indirect
golang.org/x/sys v0.5.0 // indirect
golang.org/x/term v0.5.0 // indirect
golang.org/x/text v0.7.0 // indirect
golang.org/x/tools v0.6.1-0.20230217175706-3102dad5faf9 // indirect
golang.org/x/mod v0.9.0 // indirect
golang.org/x/net v0.8.0 // indirect
golang.org/x/sys v0.6.0 // indirect
golang.org/x/term v0.6.0 // indirect
golang.org/x/text v0.8.0 // indirect
golang.org/x/tools v0.7.0 // indirect
gopkg.in/src-d/go-billy.v4 v4.3.2 // indirect
gopkg.in/src-d/go-git.v4 v4.13.1 // indirect
gopkg.in/warnings.v0 v0.1.2 // indirect

View File

@ -57,8 +57,8 @@ cloud.google.com/go/storage v1.8.0/go.mod h1:Wv1Oy7z6Yz3DshWRJFhqM/UCfaWIRTdp0RX
cloud.google.com/go/storage v1.10.0/go.mod h1:FLPqc6j+Ki4BU591ie1oL6qBQGu2Bl/tZ9ullr3+Kg0=
cloud.google.com/go/storage v1.22.1/go.mod h1:S8N1cAStu7BOeFfE8KAQzmyyLkK8p/vmRq6kuBTW58Y=
dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU=
github.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ=
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
github.com/BurntSushi/toml v1.2.1 h1:9F2/+DoOYIOksmaJFPw1tGFy1eDnIJXg+UHjuD8lTak=
github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo=
github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU=
github.com/alcortesm/tgz v0.0.0-20161220082320-9c5fe88206d7 h1:uSoVVbwJiQipAclBbw+8quDsfcvFjOpI5iCf4p/cqCs=
@ -313,7 +313,9 @@ golang.org/x/exp v0.0.0-20191129062945-2f5052295587/go.mod h1:2RIsYlXP63K8oxa1u0
golang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4=
golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4=
golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM=
golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6 h1:QE6XYQK6naiK1EPAe1g/ILLxN5RBoH5xkJk3CqlMI/Y=
golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU=
golang.org/x/exp/typeparams v0.0.0-20221208152030-732eee02a75a h1:Jw5wfR+h9mnIYH+OtGT2im5wV1YGGDora5vTv/aa5bE=
golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js=
golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=
golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
@ -341,8 +343,8 @@ golang.org/x/mod v0.4.1/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
golang.org/x/mod v0.7.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
golang.org/x/mod v0.8.0 h1:LUYupSeNrTNCGzR/hVBk2NHZO4hXcVaW1k4Qx7rjPx8=
golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
golang.org/x/mod v0.9.0 h1:KENHtAZL2y3NLMYZeHY9DW8HW8V+kQyJsY/V9JlKvCs=
golang.org/x/mod v0.9.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
@ -388,8 +390,8 @@ golang.org/x/net v0.0.0-20220624214902-1bab6f366d9e/go.mod h1:XRhObCWvk6IyKnWLug
golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
golang.org/x/net v0.1.0/go.mod h1:Cx3nUiGt4eDBEyega/BKRp+/AlGL8hYe7U9odMt2Cco=
golang.org/x/net v0.5.0/go.mod h1:DivGGAXEgPSlEBzxGzZI+ZLohi+xUj054jfeKui00ws=
golang.org/x/net v0.6.0 h1:L4ZwwTvKW9gr0ZMS1yrHD9GZhIuVjOBBnaKH+SPQK0Q=
golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
golang.org/x/net v0.8.0 h1:Zrh2ngAOFYneWTAIAPethzeaQLuHwhuBkuV6ZiRnUaQ=
golang.org/x/net v0.8.0/go.mod h1:QVkue5JL9kW//ek3r6jTKnTFis1tRmNAW2P1shuFdJc=
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
@ -491,14 +493,14 @@ golang.org/x/sys v0.0.0-20220624220833-87e55d714810/go.mod h1:oPkhp1MJrh7nUepCBc
golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.4.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.5.0 h1:MUK/U/4lj1t1oPg0HfuXDN/Z1wv31ZJ/YcPiGccS4DU=
golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.6.0 h1:MVltZSvRTcU2ljQOhs94SXPftV6DCNnZViHeQps87pQ=
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
golang.org/x/term v0.1.0/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
golang.org/x/term v0.4.0/go.mod h1:9P2UbLfCdcvo3p/nzKvsmas4TnlujnuoV9hGgYzW1lQ=
golang.org/x/term v0.5.0 h1:n2a8QNdAb0sZNpU9R1ALUXBbY+w51fCQDN+7EdxNBsY=
golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k=
golang.org/x/term v0.6.0 h1:clScbb1cHjoCkyRbWwBEUZ5H/tIFu5TAXIqaZD0Gcjw=
golang.org/x/term v0.6.0/go.mod h1:m6U89DPEgQRMq3DNkDClhWw02AUbt2daBVO4cn4Hv9U=
golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
@ -510,8 +512,8 @@ golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
golang.org/x/text v0.6.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
golang.org/x/text v0.7.0 h1:4BRB4x83lYWy72KwLD/qYDuTu7q9PjSagHvijDw7cLo=
golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
golang.org/x/text v0.8.0 h1:57P1ETyNKtuIjB4SRd15iJxuhj8Gc416Y78H3qgMh68=
golang.org/x/text v0.8.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=
golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
@ -569,10 +571,10 @@ golang.org/x/tools v0.1.4/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
golang.org/x/tools v0.5.0/go.mod h1:N+Kgy78s5I24c24dU8OfWNEotWjutIs8SnJvn5IDq+k=
golang.org/x/tools v0.6.1-0.20230217175706-3102dad5faf9 h1:IuFp2CklNBim6OdHXn/1P4VoeKt5pA2jcDKWlboqtlQ=
golang.org/x/tools v0.6.1-0.20230217175706-3102dad5faf9/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU=
golang.org/x/vuln v0.0.0-20230322160202-f2d9b5a6e023 h1:D+fLQz4/9B7Fdtbh8DpmoYjuVukotDPky6ZDsFtiVwk=
golang.org/x/vuln v0.0.0-20230322160202-f2d9b5a6e023/go.mod h1:ydpjOTRSBwOBFJRP/w5NF2HSPnFg1JxobEZQGOirxgo=
golang.org/x/tools v0.7.0 h1:W4OVu8VVOaIO0yzWMNdepAulS7YfoS3Zabrm8DOXXU4=
golang.org/x/tools v0.7.0/go.mod h1:4pg6aUX35JBAogB10C9AtvVL+qowtN4pT3CGSQex14s=
golang.org/x/vuln v0.0.0-20230325131008-9550759f8614 h1:ioRvkxpf+3iq9xvzP6AWjaBuROUad9SmjLr0QWBzxKw=
golang.org/x/vuln v0.0.0-20230325131008-9550759f8614/go.mod h1:64LpnL2PuSMzFYeCmJjYiRbroOUG9aCZYznINnF5PHE=
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
@ -786,12 +788,12 @@ honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWh
honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg=
honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k=
honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k=
honnef.co/go/tools v0.2.2 h1:MNh1AVMyVX23VUHE2O27jm6lNj3vjO5DexS4A1xvnzk=
honnef.co/go/tools v0.4.3 h1:o/n5/K5gXqk8Gozvs2cnL0F2S1/g1vcGCAx2vETjITw=
k8s.io/klog/v2 v2.80.1 h1:atnLQ121W371wYYFawwYx1aEY2eUfs4l3J72wtgAwV4=
k8s.io/klog/v2 v2.80.1/go.mod h1:y1WjHnz7Dj687irZUWR/WLkLc5N1YHtjLdmgWjndZn0=
mvdan.cc/editorconfig v0.2.0 h1:XL+7ys6ls/RKrkUNFQvEwIvNHh+JKx8Mj1pUV5wQxQE=
mvdan.cc/editorconfig v0.2.0/go.mod h1:lvnnD3BNdBYkhq+B4uBuFFKatfp02eB6HixDvEz91C0=
mvdan.cc/unparam v0.0.0-20211214103731-d0ef000c54e5 h1:Jh3LAeMt1eGpxomyu3jVkmVZWW2MxZ1qIIV2TZ/nRio=
mvdan.cc/unparam v0.0.0-20230312165513-e84e2d14e3b8 h1:VuJo4Mt0EVPychre4fNlDWDuE5AjXtPJpRUWqZDQhaI=
rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8=
rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0=
rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA=

View File

@ -8,7 +8,7 @@ go_library(
visibility = ["//:__subpackages__"],
deps = [
"//internal/crypto",
"//internal/oid",
"//internal/variant",
],
)
@ -17,7 +17,7 @@ go_test(
srcs = ["atls_test.go"],
embed = [":atls"],
deps = [
"//internal/oid",
"//internal/variant",
"@com_github_stretchr_testify//assert",
"@com_github_stretchr_testify//require",
"@org_uber_go_goleak//:goleak",

View File

@ -12,7 +12,7 @@ The protocol can be used by clients to verify a server certificate, by a server
1. The client sends a ClientHello message, setting ServerName to a random nonce.
2. The server generates an attestation statement using the clients nonce and its CC capabilities.
* The attestation is embedded in the server certificate using x509 certificate extensions with an object identifier (OID) to identify the CC attestation type. See [OID](../oid/oid.go) for implementation details.
* The attestation is embedded in the server certificate using x509 certificate extensions with an object identifier (OID) to identify the CC attestation type. Take a look at the [`variant`](../variant/variant.go) package for implementation details.
3. The client verifies the attestation statement.

View File

@ -9,6 +9,7 @@ package atls
import (
"bytes"
"context"
"crypto/ecdsa"
"crypto/elliptic"
"crypto/rand"
@ -25,9 +26,11 @@ import (
"time"
"github.com/edgelesssys/constellation/v2/internal/crypto"
"github.com/edgelesssys/constellation/v2/internal/oid"
"github.com/edgelesssys/constellation/v2/internal/variant"
)
const attestationTimeout = 30 * time.Second
// CreateAttestationServerTLSConfig creates a tls.Config object with a self-signed certificate and an embedded attestation document.
// Pass a list of validators to enable mutual aTLS.
// If issuer is nil, no attestation will be embedded.
@ -72,14 +75,14 @@ func CreateAttestationClientTLSConfig(issuer Issuer, validators []Validator) (*t
// Issuer issues an attestation document.
type Issuer interface {
oid.Getter
Issue(userData []byte, nonce []byte) (quote []byte, err error)
variant.Getter
Issue(ctx context.Context, userData []byte, nonce []byte) (quote []byte, err error)
}
// Validator is able to validate an attestation document.
type Validator interface {
oid.Getter
Validate(attDoc []byte, nonce []byte) ([]byte, error)
variant.Getter
Validate(ctx context.Context, attDoc []byte, nonce []byte) ([]byte, error)
}
// getATLSConfigForClientFunc returns a config setup function that is called once for every client connecting to the server.
@ -129,7 +132,7 @@ func getATLSConfigForClientFunc(issuer Issuer, validators []Validator) (func(*tl
// getCertificate creates a client or server certificate for aTLS connections.
// The certificate uses certificate extensions to embed an attestation document generated using nonce.
func getCertificate(issuer Issuer, priv, pub any, nonce []byte) (*tls.Certificate, error) {
func getCertificate(ctx context.Context, issuer Issuer, priv, pub any, nonce []byte) (*tls.Certificate, error) {
serialNumber, err := crypto.GenerateCertificateSerialNumber()
if err != nil {
return nil, err
@ -145,7 +148,7 @@ func getCertificate(issuer Issuer, priv, pub any, nonce []byte) (*tls.Certificat
}
// create attestation document using the nonce send by the remote party
attDoc, err := issuer.Issue(hash, nonce)
attDoc, err := issuer.Issue(ctx, hash, nonce)
if err != nil {
return nil, err
}
@ -200,7 +203,10 @@ func verifyEmbeddedReport(validators []Validator, cert *x509.Certificate, hash,
for _, ex := range cert.Extensions {
for _, validator := range validators {
if ex.Id.Equal(validator.OID()) {
userData, err := validator.Validate(ex.Value, nonce)
ctx, cancel := context.WithTimeout(context.Background(), attestationTimeout)
defer cancel()
userData, err := validator.Validate(ctx, ex.Value, nonce)
if err != nil {
return err
}
@ -308,7 +314,7 @@ func (c *clientConnection) getCertificate(cri *tls.CertificateRequestInfo) (*tls
return nil, fmt.Errorf("decode nonce: %w", err)
}
return getCertificate(c.issuer, priv, &priv.PublicKey, serverNonce)
return getCertificate(cri.Context(), c.issuer, priv, &priv.PublicKey, serverNonce)
}
// serverConnection holds state for server to client connections.
@ -340,42 +346,42 @@ func (c *serverConnection) getCertificate(chi *tls.ClientHelloInfo) (*tls.Certif
}
// create aTLS certificate using the nonce as extracted from the client-hello message
return getCertificate(c.issuer, c.privKey, &c.privKey.PublicKey, clientNonce)
return getCertificate(chi.Context(), c.issuer, c.privKey, &c.privKey.PublicKey, clientNonce)
}
// FakeIssuer fakes an issuer and can be used for tests.
type FakeIssuer struct {
oid.Getter
variant.Getter
}
// NewFakeIssuer creates a new FakeIssuer with the given OID.
func NewFakeIssuer(oid oid.Getter) *FakeIssuer {
func NewFakeIssuer(oid variant.Getter) *FakeIssuer {
return &FakeIssuer{oid}
}
// Issue marshals the user data and returns it.
func (FakeIssuer) Issue(userData []byte, nonce []byte) ([]byte, error) {
func (FakeIssuer) Issue(_ context.Context, userData []byte, nonce []byte) ([]byte, error) {
return json.Marshal(FakeAttestationDoc{UserData: userData, Nonce: nonce})
}
// FakeValidator fakes a validator and can be used for tests.
type FakeValidator struct {
oid.Getter
variant.Getter
err error // used for package internal testing only
}
// NewFakeValidator creates a new FakeValidator with the given OID.
func NewFakeValidator(oid oid.Getter) *FakeValidator {
func NewFakeValidator(oid variant.Getter) *FakeValidator {
return &FakeValidator{oid, nil}
}
// NewFakeValidators returns a slice with a single FakeValidator.
func NewFakeValidators(oid oid.Getter) []Validator {
func NewFakeValidators(oid variant.Getter) []Validator {
return []Validator{NewFakeValidator(oid)}
}
// Validate unmarshals the attestation document and verifies the nonce.
func (v FakeValidator) Validate(attDoc []byte, nonce []byte) ([]byte, error) {
func (v FakeValidator) Validate(_ context.Context, attDoc []byte, nonce []byte) ([]byte, error) {
var doc FakeAttestationDoc
if err := json.Unmarshal(attDoc, &doc); err != nil {
return nil, err

View File

@ -15,7 +15,7 @@ import (
"net/http/httptest"
"testing"
"github.com/edgelesssys/constellation/v2/internal/oid"
"github.com/edgelesssys/constellation/v2/internal/variant"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"go.uber.org/goleak"
@ -193,7 +193,7 @@ func TestClientConnectionConcurrency(t *testing.T) {
var urls []string
for i := 0; i < serverCount; i++ {
serverCfg, err := CreateAttestationServerTLSConfig(NewFakeIssuer(oid.Dummy{}), NewFakeValidators(oid.Dummy{}))
serverCfg, err := CreateAttestationServerTLSConfig(NewFakeIssuer(variant.Dummy{}), NewFakeValidators(variant.Dummy{}))
require.NoError(err)
server := httptest.NewUnstartedServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
@ -211,7 +211,7 @@ func TestClientConnectionConcurrency(t *testing.T) {
// Create client.
//
clientConfig, err := CreateAttestationClientTLSConfig(NewFakeIssuer(oid.Dummy{}), NewFakeValidators(oid.Dummy{}))
clientConfig, err := CreateAttestationClientTLSConfig(NewFakeIssuer(variant.Dummy{}), NewFakeValidators(variant.Dummy{}))
require.NoError(err)
client := http.Client{Transport: &http.Transport{TLSClientConfig: clientConfig}}
@ -266,7 +266,7 @@ func TestServerConnectionConcurrency(t *testing.T) {
var urls []string
serverCfg, err := CreateAttestationServerTLSConfig(NewFakeIssuer(oid.Dummy{}), NewFakeValidators(oid.Dummy{}))
serverCfg, err := CreateAttestationServerTLSConfig(NewFakeIssuer(variant.Dummy{}), NewFakeValidators(variant.Dummy{}))
require.NoError(err)
for i := 0; i < serverCount; i++ {
@ -285,7 +285,7 @@ func TestServerConnectionConcurrency(t *testing.T) {
// Create client.
//
clientConfig, err := CreateAttestationClientTLSConfig(NewFakeIssuer(oid.Dummy{}), NewFakeValidators(oid.Dummy{}))
clientConfig, err := CreateAttestationClientTLSConfig(NewFakeIssuer(variant.Dummy{}), NewFakeValidators(variant.Dummy{}))
require.NoError(err)
client := http.Client{Transport: &http.Transport{TLSClientConfig: clientConfig}}

View File

@ -13,7 +13,7 @@ go_library(
deps = [
"//internal/attestation/measurements",
"//internal/attestation/vtpm",
"//internal/oid",
"//internal/variant",
"@com_github_aws_aws_sdk_go_v2_config//:config",
"@com_github_aws_aws_sdk_go_v2_feature_ec2_imds//:imds",
"@com_github_aws_aws_sdk_go_v2_service_ec2//:ec2",

View File

@ -15,7 +15,7 @@ import (
"github.com/aws/aws-sdk-go-v2/feature/ec2/imds"
"github.com/edgelesssys/constellation/v2/internal/attestation/vtpm"
"github.com/edgelesssys/constellation/v2/internal/oid"
"github.com/edgelesssys/constellation/v2/internal/variant"
"github.com/google/go-tpm-tools/client"
tpmclient "github.com/google/go-tpm-tools/client"
@ -23,7 +23,7 @@ import (
// Issuer for AWS TPM attestation.
type Issuer struct {
oid.AWSNitroTPM
variant.AWSNitroTPM
*vtpm.Issuer
}

View File

@ -17,14 +17,14 @@ import (
"github.com/aws/aws-sdk-go-v2/service/ec2"
"github.com/edgelesssys/constellation/v2/internal/attestation/measurements"
"github.com/edgelesssys/constellation/v2/internal/attestation/vtpm"
"github.com/edgelesssys/constellation/v2/internal/oid"
"github.com/edgelesssys/constellation/v2/internal/variant"
"github.com/google/go-tpm-tools/proto/attest"
"github.com/google/go-tpm/tpm2"
)
// Validator for AWS TPM attestation.
type Validator struct {
oid.AWSNitroTPM
variant.AWSNitroTPM
*vtpm.Validator
getDescribeClient func(context.Context, string) (awsMetadataAPI, error)
}

View File

@ -19,7 +19,7 @@ go_library(
"//internal/attestation/vtpm",
"//internal/cloud/azure",
"//internal/crypto",
"//internal/oid",
"//internal/variant",
"@com_github_edgelesssys_go_azguestattestation//maa",
"@com_github_google_go_tpm//tpm2",
"@com_github_google_go_tpm_tools//client",

View File

@ -13,7 +13,7 @@ import (
"io"
"github.com/edgelesssys/constellation/v2/internal/attestation/vtpm"
"github.com/edgelesssys/constellation/v2/internal/oid"
"github.com/edgelesssys/constellation/v2/internal/variant"
"github.com/edgelesssys/go-azguestattestation/maa"
tpmclient "github.com/google/go-tpm-tools/client"
)
@ -22,7 +22,7 @@ const tpmAkIdx = 0x81000003
// Issuer for Azure TPM attestation.
type Issuer struct {
oid.AzureSEVSNP
variant.AzureSEVSNP
*vtpm.Issuer
imds imdsAPI

View File

@ -24,7 +24,7 @@ import (
"github.com/edgelesssys/constellation/v2/internal/attestation/measurements"
"github.com/edgelesssys/constellation/v2/internal/attestation/vtpm"
internalCrypto "github.com/edgelesssys/constellation/v2/internal/crypto"
"github.com/edgelesssys/constellation/v2/internal/oid"
"github.com/edgelesssys/constellation/v2/internal/variant"
"github.com/google/go-tpm-tools/proto/attest"
"github.com/google/go-tpm/tpm2"
)
@ -40,7 +40,7 @@ const (
// Validator for Azure confidential VM attestation.
type Validator struct {
oid.AzureSEVSNP
variant.AzureSEVSNP
*vtpm.Validator
hclValidator hclAkValidator
maa maaValidator

View File

@ -14,7 +14,7 @@ go_library(
"//internal/attestation/measurements",
"//internal/attestation/vtpm",
"//internal/crypto",
"//internal/oid",
"//internal/variant",
"@com_github_google_go_tpm//tpm2",
"@com_github_google_go_tpm_tools//client",
"@com_github_google_go_tpm_tools//proto/attest",

View File

@ -16,7 +16,7 @@ import (
"net/http"
"github.com/edgelesssys/constellation/v2/internal/attestation/vtpm"
"github.com/edgelesssys/constellation/v2/internal/oid"
"github.com/edgelesssys/constellation/v2/internal/variant"
tpmclient "github.com/google/go-tpm-tools/client"
"github.com/google/go-tpm/tpm2"
)
@ -28,7 +28,7 @@ const (
// Issuer for Azure trusted launch TPM attestation.
type Issuer struct {
oid.AzureTrustedLaunch
variant.AzureTrustedLaunch
*vtpm.Issuer
hClient httpClient
}

View File

@ -18,7 +18,7 @@ import (
"github.com/edgelesssys/constellation/v2/internal/attestation/measurements"
"github.com/edgelesssys/constellation/v2/internal/attestation/vtpm"
certutil "github.com/edgelesssys/constellation/v2/internal/crypto"
"github.com/edgelesssys/constellation/v2/internal/oid"
"github.com/edgelesssys/constellation/v2/internal/variant"
"github.com/google/go-tpm-tools/proto/attest"
"github.com/google/go-tpm/tpm2"
)
@ -29,7 +29,7 @@ var ameRoot = mustParseX509("-----BEGIN CERTIFICATE-----\nMIIFVjCCAz6gAwIBAgIQJd
// Validator for Azure trusted launch VM attestation.
type Validator struct {
oid.AzureTrustedLaunch
variant.AzureTrustedLaunch
*vtpm.Validator
roots *x509.CertPool
}

View File

@ -16,7 +16,7 @@ go_library(
"//internal/attestation/measurements",
"//internal/attestation/qemu",
"//internal/attestation/vtpm",
"//internal/oid",
"//internal/variant",
],
)
@ -26,7 +26,7 @@ go_test(
embed = [":choose"],
deps = [
"//internal/attestation/idkeydigest",
"//internal/oid",
"//internal/variant",
"@com_github_stretchr_testify//assert",
"@com_github_stretchr_testify//require",
],

View File

@ -18,47 +18,47 @@ import (
"github.com/edgelesssys/constellation/v2/internal/attestation/measurements"
"github.com/edgelesssys/constellation/v2/internal/attestation/qemu"
"github.com/edgelesssys/constellation/v2/internal/attestation/vtpm"
"github.com/edgelesssys/constellation/v2/internal/oid"
"github.com/edgelesssys/constellation/v2/internal/variant"
)
// Issuer returns the issuer for the given variant.
func Issuer(variant oid.Getter, log vtpm.AttestationLogger) (atls.Issuer, error) {
switch variant {
case oid.AWSNitroTPM{}:
func Issuer(attestationVariant variant.Variant, log vtpm.AttestationLogger) (atls.Issuer, error) {
switch attestationVariant {
case variant.AWSNitroTPM{}:
return aws.NewIssuer(log), nil
case oid.AzureTrustedLaunch{}:
case variant.AzureTrustedLaunch{}:
return trustedlaunch.NewIssuer(log), nil
case oid.AzureSEVSNP{}:
case variant.AzureSEVSNP{}:
return snp.NewIssuer(log), nil
case oid.GCPSEVES{}:
case variant.GCPSEVES{}:
return gcp.NewIssuer(log), nil
case oid.QEMUVTPM{}:
case variant.QEMUVTPM{}:
return qemu.NewIssuer(log), nil
case oid.Dummy{}:
return atls.NewFakeIssuer(oid.Dummy{}), nil
case variant.Dummy{}:
return atls.NewFakeIssuer(variant.Dummy{}), nil
default:
return nil, fmt.Errorf("unknown attestation variant: %s", variant)
return nil, fmt.Errorf("unknown attestation variant: %s", attestationVariant)
}
}
// Validator returns the validator for the given variant.
func Validator(
variant oid.Getter, measurements measurements.M, idKeyCfg idkeydigest.Config, log vtpm.AttestationLogger,
attestationVariant variant.Variant, measurements measurements.M, idKeyCfg idkeydigest.Config, log vtpm.AttestationLogger,
) (atls.Validator, error) {
switch variant {
case oid.AWSNitroTPM{}:
switch attestationVariant {
case variant.AWSNitroTPM{}:
return aws.NewValidator(measurements, log), nil
case oid.AzureTrustedLaunch{}:
case variant.AzureTrustedLaunch{}:
return trustedlaunch.NewValidator(measurements, log), nil
case oid.AzureSEVSNP{}:
case variant.AzureSEVSNP{}:
return snp.NewValidator(measurements, idKeyCfg, log), nil
case oid.GCPSEVES{}:
case variant.GCPSEVES{}:
return gcp.NewValidator(measurements, log), nil
case oid.QEMUVTPM{}:
case variant.QEMUVTPM{}:
return qemu.NewValidator(measurements, log), nil
case oid.Dummy{}:
return atls.NewFakeValidator(oid.Dummy{}), nil
case variant.Dummy{}:
return atls.NewFakeValidator(variant.Dummy{}), nil
default:
return nil, fmt.Errorf("unknown attestation variant: %s", variant)
return nil, fmt.Errorf("unknown attestation variant: %s", attestationVariant)
}
}

View File

@ -11,33 +11,33 @@ import (
"testing"
"github.com/edgelesssys/constellation/v2/internal/attestation/idkeydigest"
"github.com/edgelesssys/constellation/v2/internal/oid"
"github.com/edgelesssys/constellation/v2/internal/variant"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)
func TestIssuer(t *testing.T) {
testCases := map[string]struct {
variant oid.Getter
variant variant.Variant
wantErr bool
}{
"aws-nitro-tpm": {
variant: oid.AWSNitroTPM{},
variant: variant.AWSNitroTPM{},
},
"azure-sev-snp": {
variant: oid.AzureSEVSNP{},
variant: variant.AzureSEVSNP{},
},
"azure-trusted-launch": {
variant: oid.AzureTrustedLaunch{},
variant: variant.AzureTrustedLaunch{},
},
"gcp-sev-es": {
variant: oid.GCPSEVES{},
variant: variant.GCPSEVES{},
},
"qemu-vtpm": {
variant: oid.QEMUVTPM{},
variant: variant.QEMUVTPM{},
},
"dummy": {
variant: oid.Dummy{},
variant: variant.Dummy{},
},
"unknown": {
variant: unknownVariant{},
@ -64,26 +64,26 @@ func TestIssuer(t *testing.T) {
func TestValidator(t *testing.T) {
testCases := map[string]struct {
variant oid.Getter
variant variant.Variant
wantErr bool
}{
"aws-nitro-tpm": {
variant: oid.AWSNitroTPM{},
variant: variant.AWSNitroTPM{},
},
"azure-sev-snp": {
variant: oid.AzureSEVSNP{},
variant: variant.AzureSEVSNP{},
},
"azure-trusted-launch": {
variant: oid.AzureTrustedLaunch{},
variant: variant.AzureTrustedLaunch{},
},
"gcp-sev-es": {
variant: oid.GCPSEVES{},
variant: variant.GCPSEVES{},
},
"qemu-vtpm": {
variant: oid.QEMUVTPM{},
variant: variant.QEMUVTPM{},
},
"dummy": {
variant: oid.Dummy{},
variant: variant.Dummy{},
},
"unknown": {
variant: unknownVariant{},
@ -113,3 +113,11 @@ type unknownVariant struct{}
func (unknownVariant) OID() asn1.ObjectIdentifier {
return asn1.ObjectIdentifier{1, 3, 9900, 9999, 9999}
}
func (unknownVariant) String() string {
return "unknown"
}
func (unknownVariant) Equal(other variant.Getter) bool {
return other.OID().Equal(unknownVariant{}.OID())
}

View File

@ -13,7 +13,7 @@ go_library(
deps = [
"//internal/attestation/measurements",
"//internal/attestation/vtpm",
"//internal/oid",
"//internal/variant",
"@com_github_google_go_tpm_tools//client",
"@com_github_google_go_tpm_tools//proto/attest",
"@com_github_googleapis_gax_go_v2//:gax-go",

View File

@ -14,14 +14,14 @@ import (
"cloud.google.com/go/compute/metadata"
"github.com/edgelesssys/constellation/v2/internal/attestation/vtpm"
"github.com/edgelesssys/constellation/v2/internal/oid"
"github.com/edgelesssys/constellation/v2/internal/variant"
tpmclient "github.com/google/go-tpm-tools/client"
"github.com/google/go-tpm-tools/proto/attest"
)
// Issuer for GCP confidential VM attestation.
type Issuer struct {
oid.GCPSEVES
variant.GCPSEVES
*vtpm.Issuer
}

View File

@ -18,7 +18,7 @@ import (
"cloud.google.com/go/compute/apiv1/computepb"
"github.com/edgelesssys/constellation/v2/internal/attestation/measurements"
"github.com/edgelesssys/constellation/v2/internal/attestation/vtpm"
"github.com/edgelesssys/constellation/v2/internal/oid"
"github.com/edgelesssys/constellation/v2/internal/variant"
"github.com/google/go-tpm-tools/proto/attest"
"github.com/googleapis/gax-go/v2"
"google.golang.org/api/option"
@ -28,7 +28,7 @@ const minimumGceVersion = 1
// Validator for GCP confidential VM attestation.
type Validator struct {
oid.GCPSEVES
variant.GCPSEVES
*vtpm.Validator
restClient func(context.Context, ...option.ClientOption) (gcpRestClient, error)

View File

@ -143,7 +143,7 @@ func (m *M) EqualTo(other M) bool {
func (m *M) GetEnforced() []uint32 {
var enforced []uint32
for idx, measurement := range *m {
if !measurement.ValidationOpt {
if measurement.ValidationOpt == Enforce {
enforced = append(enforced, idx)
}
}

View File

@ -12,7 +12,7 @@ go_library(
deps = [
"//internal/attestation/measurements",
"//internal/attestation/vtpm",
"//internal/oid",
"//internal/variant",
"@com_github_google_go_tpm//tpm2",
"@com_github_google_go_tpm_tools//client",
"@com_github_google_go_tpm_tools//proto/attest",

View File

@ -11,13 +11,13 @@ import (
"io"
"github.com/edgelesssys/constellation/v2/internal/attestation/vtpm"
"github.com/edgelesssys/constellation/v2/internal/oid"
"github.com/edgelesssys/constellation/v2/internal/variant"
tpmclient "github.com/google/go-tpm-tools/client"
)
// Issuer for qemu TPM attestation.
type Issuer struct {
oid.QEMUVTPM
variant.QEMUVTPM
*vtpm.Issuer
}

View File

@ -12,14 +12,14 @@ import (
"github.com/edgelesssys/constellation/v2/internal/attestation/measurements"
"github.com/edgelesssys/constellation/v2/internal/attestation/vtpm"
"github.com/edgelesssys/constellation/v2/internal/oid"
"github.com/edgelesssys/constellation/v2/internal/variant"
"github.com/google/go-tpm-tools/proto/attest"
"github.com/google/go-tpm/tpm2"
)
// Validator for QEMU VM attestation.
type Validator struct {
oid.QEMUVTPM
variant.QEMUVTPM
*vtpm.Validator
}

View File

@ -107,7 +107,7 @@ func NewIssuer(
}
// Issue generates an attestation document using a TPM.
func (i *Issuer) Issue(userData []byte, nonce []byte) (res []byte, err error) {
func (i *Issuer) Issue(ctx context.Context, userData []byte, nonce []byte) (res []byte, err error) {
i.log.Infof("Issuing attestation statement")
defer func() {
if err != nil {
@ -136,7 +136,7 @@ func (i *Issuer) Issue(userData []byte, nonce []byte) (res []byte, err error) {
}
// Fetch instance info of the VM
instanceInfo, err := i.getInstanceInfo(context.TODO(), tpm, extraData) // TODO(daniel-weisse): update Issue/Validate to use context
instanceInfo, err := i.getInstanceInfo(ctx, tpm, extraData)
if err != nil {
return nil, fmt.Errorf("fetching instance info: %w", err)
}
@ -181,7 +181,7 @@ func NewValidator(expected measurements.M, getTrustedKey GetTPMTrustedAttestatio
}
// Validate a TPM based attestation.
func (v *Validator) Validate(attDocRaw []byte, nonce []byte) (userData []byte, err error) {
func (v *Validator) Validate(ctx context.Context, attDocRaw []byte, nonce []byte) (userData []byte, err error) {
v.log.Infof("Validating attestation document")
defer func() {
if err != nil {
@ -197,7 +197,7 @@ func (v *Validator) Validate(attDocRaw []byte, nonce []byte) (userData []byte, e
extraData := makeExtraData(attDoc.UserData, nonce)
// Verify and retrieve the trusted attestation public key using the provided instance info
aKP, err := v.getTrustedKey(context.TODO(), attDoc, extraData)
aKP, err := v.getTrustedKey(ctx, attDoc, extraData)
if err != nil {
return nil, fmt.Errorf("validating attestation public key: %w", err)
}
@ -227,7 +227,7 @@ func (v *Validator) Validate(attDocRaw []byte, nonce []byte) (userData []byte, e
}
for idx, pcr := range v.expected {
if !bytes.Equal(pcr.Expected[:], attDoc.Attestation.Quotes[quoteIdx].Pcrs.Pcrs[idx]) {
if !pcr.ValidationOpt {
if pcr.ValidationOpt == measurements.Enforce {
return nil, fmt.Errorf("untrusted PCR value at PCR index %d", idx)
}
v.log.Warnf("Encountered untrusted PCR value at index %d", idx)

View File

@ -84,7 +84,9 @@ func TestValidate(t *testing.T) {
nonce := []byte{1, 2, 3, 4}
challenge := []byte("Constellation")
attDocRaw, err := issuer.Issue(challenge, nonce)
ctx := context.Background()
attDocRaw, err := issuer.Issue(ctx, challenge, nonce)
require.NoError(err)
var attDoc AttestationDocument
@ -93,26 +95,26 @@ func TestValidate(t *testing.T) {
require.Equal(challenge, attDoc.UserData)
// valid test
out, err := validator.Validate(attDocRaw, nonce)
out, err := validator.Validate(ctx, attDocRaw, nonce)
require.NoError(err)
require.Equal(challenge, out)
// validation must fail after bootstrapping (change of enforced PCR)
require.NoError(MarkNodeAsBootstrapped(tpmOpen, []byte{2}))
attDocBootstrappedRaw, err := issuer.Issue(challenge, nonce)
attDocBootstrappedRaw, err := issuer.Issue(ctx, challenge, nonce)
require.NoError(err)
_, err = validator.Validate(attDocBootstrappedRaw, nonce)
_, err = validator.Validate(ctx, attDocBootstrappedRaw, nonce)
require.Error(err)
// userData must be bound to PCR state
attDocBootstrappedRaw, err = issuer.Issue([]byte{2, 3}, nonce)
attDocBootstrappedRaw, err = issuer.Issue(ctx, []byte{2, 3}, nonce)
require.NoError(err)
var attDocBootstrapped AttestationDocument
require.NoError(json.Unmarshal(attDocBootstrappedRaw, &attDocBootstrapped))
attDocBootstrapped.Attestation = attDoc.Attestation
attDocBootstrappedRaw, err = json.Marshal(attDocBootstrapped)
require.NoError(err)
_, err = validator.Validate(attDocBootstrappedRaw, nonce)
_, err = validator.Validate(ctx, attDocBootstrappedRaw, nonce)
require.Error(err)
expectedPCRs := measurements.M{
@ -141,7 +143,7 @@ func TestValidate(t *testing.T) {
fakeValidateCVM,
warnLog,
)
out, err = warningValidator.Validate(attDocRaw, nonce)
out, err = warningValidator.Validate(ctx, attDocRaw, nonce)
require.NoError(err)
assert.Equal(t, challenge, out)
assert.Len(t, warnLog.warnings, 4)
@ -240,7 +242,7 @@ func TestValidate(t *testing.T) {
t.Run(name, func(t *testing.T) {
assert := assert.New(t)
_, err = tc.validator.Validate(tc.attDoc, tc.nonce)
_, err = tc.validator.Validate(ctx, tc.attDoc, tc.nonce)
if tc.wantErr {
assert.Error(err)
} else {
@ -316,7 +318,7 @@ func TestFailIssuer(t *testing.T) {
tc.issuer.log = logger.NewTest(t)
_, err := tc.issuer.Issue(tc.userData, tc.nonce)
_, err := tc.issuer.Issue(context.Background(), tc.userData, tc.nonce)
assert.Error(err)
})
}

View File

@ -22,7 +22,7 @@ go_library(
"//internal/config/instancetypes",
"//internal/constants",
"//internal/file",
"//internal/oid",
"//internal/variant",
"//internal/versions",
"//internal/versionsapi",
"@com_github_go_playground_locales//en",
@ -49,7 +49,7 @@ go_test(
"//internal/config/instancetypes",
"//internal/constants",
"//internal/file",
"//internal/oid",
"//internal/variant",
"@com_github_go_playground_locales//en",
"@com_github_go_playground_universal_translator//:universal-translator",
"@com_github_go_playground_validator_v10//:validator",

View File

@ -23,6 +23,7 @@ import (
"fmt"
"io/fs"
"os"
"reflect"
"strings"
"github.com/edgelesssys/constellation/v2/internal/attestation/idkeydigest"
@ -183,7 +184,7 @@ type AzureConfig struct {
DeployCSIDriver *bool `yaml:"deployCSIDriver" validate:"required"`
// description: |
// Use Confidential VMs. Always needs to be true.
ConfidentialVM *bool `yaml:"confidentialVM" validate:"required"`
ConfidentialVM *bool `yaml:"confidentialVM,omitempty" validate:"omitempty,deprecated"` // TODO: v2.8 remove
// description: |
// Enable secure boot for VMs. If enabled, the OS image has to include a virtual machine guest state (VMGS) blob.
SecureBoot *bool `yaml:"secureBoot" validate:"required"`
@ -330,7 +331,6 @@ func Default() *Config {
DeployCSIDriver: toPtr(true),
IDKeyDigest: idkeydigest.DefaultsFor(cloudprovider.Azure),
EnforceIDKeyDigest: idkeydigest.MAAFallback,
ConfidentialVM: toPtr(true),
SecureBoot: toPtr(false),
Measurements: measurements.DefaultsFor(cloudprovider.Azure),
},
@ -459,11 +459,6 @@ func (c *Config) RemoveProviderExcept(provider cloudprovider.Provider) {
}
}
// IsAzureNonCVM checks whether the chosen provider is azure and confidential VMs are disabled.
func (c *Config) IsAzureNonCVM() bool {
return c.Provider.Azure != nil && c.Provider.Azure.ConfidentialVM != nil && !*c.Provider.Azure.ConfidentialVM
}
// IsDebugCluster checks whether the cluster is configured as a debug cluster.
func (c *Config) IsDebugCluster() bool {
if c.DebugCluster != nil && *c.DebugCluster {
@ -522,23 +517,6 @@ func (c *Config) IDKeyDigestPolicy() idkeydigest.EnforceIDKeyDigest {
return idkeydigest.Unknown
}
// EnforcedPCRs returns the list of enforced PCRs for the configured cloud provider.
func (c *Config) EnforcedPCRs() []uint32 {
provider := c.GetProvider()
switch provider {
case cloudprovider.AWS:
return c.Provider.AWS.Measurements.GetEnforced()
case cloudprovider.Azure:
return c.Provider.Azure.Measurements.GetEnforced()
case cloudprovider.GCP:
return c.Provider.GCP.Measurements.GetEnforced()
case cloudprovider.QEMU:
return c.Provider.QEMU.Measurements.GetEnforced()
default:
return nil
}
}
// IDKeyDigests returns the ID Key Digests for the configured cloud provider.
func (c *Config) IDKeyDigests() idkeydigest.IDKeyDigests {
if c.Provider.Azure != nil {
@ -561,6 +539,17 @@ func (c *Config) Validate(force bool) error {
return err
}
// Register name function to return yaml name tag
// This makes sure methods like fl.FieldName() return the yaml name tag instead of the struct field name
// e.g. struct{DataType string `yaml:"foo,omitempty"`} will return `foo` instead of `DataType` when calling fl.FieldName()
validate.RegisterTagNameFunc(func(fld reflect.StructField) string {
name, _, _ := strings.Cut(fld.Tag.Get("yaml"), ",")
if name == "-" {
return ""
}
return name
})
// Register AWS, Azure & GCP InstanceType validation error types
if err := validate.RegisterTranslation("aws_instance_type", trans, registerTranslateAWSInstanceTypeError, translateAWSInstanceTypeError); err != nil {
return err
@ -630,7 +619,7 @@ func (c *Config) Validate(force bool) error {
}
// register custom validator with label azure_instance_type to validate the Azure instance type from config input.
if err := validate.RegisterValidation("azure_instance_type", validateAzureInstanceType); err != nil {
if err := validate.RegisterValidation("azure_instance_type", c.validateAzureInstanceType); err != nil {
return err
}
@ -643,6 +632,10 @@ func (c *Config) Validate(force bool) error {
return err
}
if err := validate.RegisterValidation("deprecated", warnDeprecated); err != nil {
return err
}
// Register provider validation
validate.RegisterStructValidation(validateProvider, ProviderConfig{})

View File

@ -251,7 +251,7 @@ func init() {
AzureConfigDoc.Fields[9].Comments[encoder.LineComment] = "Deploy Azure Disk CSI driver with on-node encryption. For details see: https://docs.edgeless.systems/constellation/architecture/encrypted-storage"
AzureConfigDoc.Fields[10].Name = "confidentialVM"
AzureConfigDoc.Fields[10].Type = "bool"
AzureConfigDoc.Fields[10].Note = ""
AzureConfigDoc.Fields[10].Note = "TODO: v2.8 remove\n"
AzureConfigDoc.Fields[10].Description = "Use Confidential VMs. Always needs to be true."
AzureConfigDoc.Fields[10].Comments[encoder.LineComment] = "Use Confidential VMs. Always needs to be true."
AzureConfigDoc.Fields[11].Name = "secureBoot"

View File

@ -16,7 +16,7 @@ import (
"github.com/edgelesssys/constellation/v2/internal/config/instancetypes"
"github.com/edgelesssys/constellation/v2/internal/constants"
"github.com/edgelesssys/constellation/v2/internal/file"
"github.com/edgelesssys/constellation/v2/internal/oid"
"github.com/edgelesssys/constellation/v2/internal/variant"
"github.com/go-playground/locales/en"
ut "github.com/go-playground/universal-translator"
"github.com/go-playground/validator/v10"
@ -123,7 +123,7 @@ func TestNewWithDefaultOptions(t *testing.T) {
c := Default()
c.RemoveProviderExcept(cloudprovider.Azure)
c.Image = "v" + constants.VersionInfo()
c.AttestationVariant = oid.AzureSEVSNP{}.String()
c.AttestationVariant = variant.AzureSEVSNP{}.String()
c.Provider.Azure.SubscriptionID = "f4278079-288c-4766-a98c-ab9d5dba01a5"
c.Provider.Azure.TenantID = "d4ff9d63-6d6d-4042-8f6a-21e804add5aa"
c.Provider.Azure.Location = "westus"
@ -143,7 +143,7 @@ func TestNewWithDefaultOptions(t *testing.T) {
c := Default()
c.RemoveProviderExcept(cloudprovider.Azure)
c.Image = "v" + constants.VersionInfo()
c.AttestationVariant = oid.AzureSEVSNP{}.String()
c.AttestationVariant = variant.AzureSEVSNP{}.String()
c.Provider.Azure.SubscriptionID = "f4278079-288c-4766-a98c-ab9d5dba01a5"
c.Provider.Azure.TenantID = "d4ff9d63-6d6d-4042-8f6a-21e804add5aa"
c.Provider.Azure.Location = "westus"
@ -235,7 +235,7 @@ func TestValidate(t *testing.T) {
cnf: func() *Config {
cnf := Default()
cnf.Image = "v" + constants.VersionInfo()
cnf.AttestationVariant = oid.AzureSEVSNP{}.String()
cnf.AttestationVariant = variant.AzureSEVSNP{}.String()
az := cnf.Provider.Azure
az.SubscriptionID = "01234567-0123-0123-0123-0123456789ab"
az.TenantID = "01234567-0123-0123-0123-0123456789ab"
@ -265,7 +265,7 @@ func TestValidate(t *testing.T) {
cnf: func() *Config {
cnf := Default()
cnf.Image = "v" + constants.VersionInfo()
cnf.AttestationVariant = oid.GCPSEVES{}.String()
cnf.AttestationVariant = variant.GCPSEVES{}.String()
gcp := cnf.Provider.GCP
gcp.Region = "test-region"
gcp.Project = "test-project"

View File

@ -20,7 +20,7 @@ import (
"github.com/edgelesssys/constellation/v2/internal/compatibility"
"github.com/edgelesssys/constellation/v2/internal/config/instancetypes"
"github.com/edgelesssys/constellation/v2/internal/constants"
"github.com/edgelesssys/constellation/v2/internal/oid"
"github.com/edgelesssys/constellation/v2/internal/variant"
"github.com/edgelesssys/constellation/v2/internal/versions"
"github.com/edgelesssys/constellation/v2/internal/versionsapi"
ut "github.com/go-playground/universal-translator"
@ -102,14 +102,12 @@ func validateAWSInstanceType(fl validator.FieldLevel) bool {
return validInstanceTypeForProvider(fl.Field().String(), false, cloudprovider.AWS)
}
func validateAzureInstanceType(fl validator.FieldLevel) bool {
azureConfig := fl.Parent().Interface().(AzureConfig)
var acceptNonCVM bool
if azureConfig.ConfidentialVM != nil {
// This is the inverse of the config value (acceptNonCVMs is true if confidentialVM is false).
// We could make the validator the other way around, but this should be an explicit bypass rather than checking if CVMs are "allowed".
acceptNonCVM = !*azureConfig.ConfidentialVM
func (c *Config) validateAzureInstanceType(fl validator.FieldLevel) bool {
attestVariant, err := variant.FromString(c.AttestationVariant)
if err != nil {
return false
}
acceptNonCVM := attestVariant.Equal(variant.AzureTrustedLaunch{})
return validInstanceTypeForProvider(fl.Field().String(), acceptNonCVM, cloudprovider.Azure)
}
@ -282,7 +280,12 @@ func registerTranslateAzureInstanceTypeError(ut ut.Translator) error {
func (c *Config) translateAzureInstanceTypeError(ut ut.Translator, fe validator.FieldError) string {
// Suggest trusted launch VMs if confidential VMs have been specifically disabled
var t string
if c.Provider.Azure != nil && c.Provider.Azure.ConfidentialVM != nil && !*c.Provider.Azure.ConfidentialVM {
attestVariant, err := variant.FromString(c.AttestationVariant)
if err != nil {
return ""
}
if attestVariant.Equal(variant.AzureTrustedLaunch{}) {
t, _ = ut.T("azure_instance_type", fe.Field(), fmt.Sprintf("%v", instancetypes.AzureTrustedLaunchInstanceTypes))
} else {
t, _ = ut.T("azure_instance_type", fe.Field(), fmt.Sprintf("%v", instancetypes.AzureCVMInstanceTypes))
@ -400,7 +403,7 @@ func validateVersionCompatibility(fl validator.FieldLevel) bool {
}
func validateVersionCompatibilityHelper(binaryVersion, fieldName, configuredVersion string) error {
if fieldName == "Image" {
if fieldName == "image" {
imageVersion, err := versionsapi.NewVersionFromShortPath(configuredVersion, versionsapi.VersionKindImage)
if err != nil {
return err
@ -408,7 +411,7 @@ func validateVersionCompatibilityHelper(binaryVersion, fieldName, configuredVers
configuredVersion = imageVersion.Version
}
if fieldName == "MicroserviceVersion" {
if fieldName == "microserviceVersion" {
cliVersion := compatibility.EnsurePrefixV(binaryVersion)
serviceVersion := compatibility.EnsurePrefixV(configuredVersion)
if semver.Compare(cliVersion, serviceVersion) == -1 {
@ -482,23 +485,23 @@ func (c *Config) validAttestVariant(_ validator.FieldLevel) bool {
// TODO: v2.8: remove variant fallback and make variant a required field
c.addMissingVariant()
variant, err := oid.FromString(c.AttestationVariant)
attestationVariant, err := variant.FromString(c.AttestationVariant)
if err != nil {
return false
}
// make sure the variant is valid for the chosen CSP
switch variant {
case oid.AWSNitroTPM{}:
switch attestationVariant {
case variant.AWSNitroTPM{}:
return c.Provider.AWS != nil
case oid.AzureSEVSNP{}, oid.AzureTrustedLaunch{}:
case variant.AzureSEVSNP{}, variant.AzureTrustedLaunch{}:
return c.Provider.Azure != nil
// TODO(malt3): remove this case once we have a vTPM for OpenStack
case oid.Dummy{}:
case variant.Dummy{}:
return c.Provider.OpenStack != nil
case oid.GCPSEVES{}:
case variant.GCPSEVES{}:
return c.Provider.GCP != nil
case oid.QEMUVTPM{}:
case variant.QEMUVTPM{}:
return c.Provider.QEMU != nil
default:
return false
@ -513,12 +516,21 @@ func (c *Config) addMissingVariant() {
switch c.GetProvider() {
case cloudprovider.AWS:
c.AttestationVariant = oid.AWSNitroTPM{}.String()
c.AttestationVariant = variant.AWSNitroTPM{}.String()
case cloudprovider.Azure:
c.AttestationVariant = oid.AzureSEVSNP{}.String()
c.AttestationVariant = variant.AzureSEVSNP{}.String()
case cloudprovider.GCP:
c.AttestationVariant = oid.GCPSEVES{}.String()
c.AttestationVariant = variant.GCPSEVES{}.String()
case cloudprovider.QEMU:
c.AttestationVariant = oid.QEMUVTPM{}.String()
c.AttestationVariant = variant.QEMUVTPM{}.String()
}
}
func warnDeprecated(fl validator.FieldLevel) bool {
fmt.Fprintf(
os.Stderr,
"WARNING: The config key %q is deprecated and will be removed in an upcoming version.\n",
fl.FieldName(),
)
return true
}

View File

@ -38,7 +38,7 @@ func TestValidateVersionCompatibilityHelper(t *testing.T) {
t.Run(name, func(t *testing.T) {
assert := assert.New(t)
err := validateVersionCompatibilityHelper(tc.cli, "Image", tc.target)
err := validateVersionCompatibilityHelper(tc.cli, "image", tc.target)
if tc.wantError {
assert.Error(err)
return

View File

@ -86,7 +86,7 @@ type fakeIssuer struct {
fakeOID
}
func (fakeIssuer) Issue(userData []byte, nonce []byte) ([]byte, error) {
func (fakeIssuer) Issue(_ context.Context, userData []byte, nonce []byte) ([]byte, error) {
return json.Marshal(fakeDoc{UserData: userData, Nonce: nonce})
}
@ -95,7 +95,7 @@ type fakeValidator struct {
err error
}
func (v fakeValidator) Validate(attDoc []byte, nonce []byte) ([]byte, error) {
func (v fakeValidator) Validate(_ context.Context, attDoc []byte, nonce []byte) ([]byte, error) {
var doc fakeDoc
if err := json.Unmarshal(attDoc, &doc); err != nil {
return nil, err

View File

@ -22,7 +22,7 @@ go_test(
"//internal/atls",
"//internal/grpc/atlscredentials",
"//internal/grpc/testdialer",
"//internal/oid",
"//internal/variant",
"@com_github_stretchr_testify//assert",
"@com_github_stretchr_testify//require",
"@org_golang_google_grpc//:go_default_library",

View File

@ -13,7 +13,7 @@ import (
"github.com/edgelesssys/constellation/v2/internal/atls"
"github.com/edgelesssys/constellation/v2/internal/grpc/atlscredentials"
"github.com/edgelesssys/constellation/v2/internal/grpc/testdialer"
"github.com/edgelesssys/constellation/v2/internal/oid"
"github.com/edgelesssys/constellation/v2/internal/variant"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"go.uber.org/goleak"
@ -75,8 +75,8 @@ func TestDial(t *testing.T) {
require := require.New(t)
netDialer := testdialer.NewBufconnDialer()
dialer := New(nil, atls.NewFakeValidator(oid.Dummy{}), netDialer)
server := newServer(oid.Dummy{}, tc.tls)
dialer := New(nil, atls.NewFakeValidator(variant.Dummy{}), netDialer)
server := newServer(variant.Dummy{}, tc.tls)
api := &testAPI{}
grpc_testing.RegisterTestServiceServer(server, api)
go server.Serve(netDialer.GetListener("192.0.2.1:1234"))
@ -97,7 +97,7 @@ func TestDial(t *testing.T) {
}
}
func newServer(oid oid.Getter, tls bool) *grpc.Server {
func newServer(oid variant.Getter, tls bool) *grpc.Server {
if tls {
creds := atlscredentials.New(atls.NewFakeIssuer(oid), nil)
return grpc.NewServer(grpc.Creds(creds))

View File

@ -6,3 +6,10 @@ go_library(
importpath = "github.com/edgelesssys/constellation/v2/internal/oid",
visibility = ["//:__subpackages__"],
)
go_library(
name = "variant",
srcs = ["variant.go"],
importpath = "github.com/edgelesssys/constellation/v2/internal/variant",
visibility = ["//:__subpackages__"],
)

View File

@ -5,7 +5,11 @@ SPDX-License-Identifier: AGPL-3.0-only
*/
/*
Package oid defines OIDs for different CSPs. Currently this is used in attested TLS to distinguish the attestation documents.
Package variant defines Attestation variants for different CSPs.
Each variant defines an OID, a string representation, and a function to compare it to other OIDs.
The OID is used in attested TLS to distinguish the attestation documents.
OIDs beginning with 1.3.9900 are reserved and can be used without registration.
* The 1.3.9900.1 branch is reserved for placeholder values and testing.
@ -20,21 +24,41 @@ OIDs beginning with 1.3.9900 are reserved and can be used without registration.
Deprecated OIDs should never be reused for different purposes.
Instead, new OIDs should be added in the appropriate branch at the next available index.
String representation should be lowercase and contain only letters, numbers, and hyphens.
They should be prefixed with the branch name, e.g. all variants in the 1.3.9900.2 (AWS) branch should start with "aws-".
Each variant should have a unique string representation.
*/
package oid
package variant
import (
"encoding/asn1"
"fmt"
)
const (
dummy = "dummy"
awsNitroTPM = "aws-nitro-tpm"
gcpSEVES = "gcp-sev-es"
azureSEVSNP = "azure-sev-snp"
azureTrustedLaunch = "azure-trustedlaunch"
qemuVTPM = "qemu-vtpm"
)
// Getter returns an ASN.1 Object Identifier.
type Getter interface {
OID() asn1.ObjectIdentifier
}
// Variant describes an attestation variant.
type Variant interface {
Getter
String() string
Equal(other Getter) bool
}
// FromString returns the OID for the given string.
func FromString(oid string) (Getter, error) {
func FromString(oid string) (Variant, error) {
switch oid {
case dummy:
return Dummy{}, nil
@ -65,6 +89,11 @@ func (Dummy) String() string {
return dummy
}
// Equal returns true if the other variant is also a Dummy.
func (Dummy) Equal(other Getter) bool {
return other.OID().Equal(Dummy{}.OID())
}
// AWSNitroTPM holds the AWS nitro TPM OID.
type AWSNitroTPM struct{}
@ -78,6 +107,11 @@ func (AWSNitroTPM) String() string {
return awsNitroTPM
}
// Equal returns true if the other variant is also AWSNitroTPM.
func (AWSNitroTPM) Equal(other Getter) bool {
return other.OID().Equal(AWSNitroTPM{}.OID())
}
// GCPSEVES holds the GCP SEV-ES OID.
type GCPSEVES struct{}
@ -91,6 +125,11 @@ func (GCPSEVES) String() string {
return gcpSEVES
}
// Equal returns true if the other variant is also GCPSEVES.
func (GCPSEVES) Equal(other Getter) bool {
return other.OID().Equal(GCPSEVES{}.OID())
}
// AzureSEVSNP holds the OID for Azure SNP CVMs.
type AzureSEVSNP struct{}
@ -104,6 +143,11 @@ func (AzureSEVSNP) String() string {
return azureSEVSNP
}
// Equal returns true if the other variant is also AzureSEVSNP.
func (AzureSEVSNP) Equal(other Getter) bool {
return other.OID().Equal(AzureSEVSNP{}.OID())
}
// AzureTrustedLaunch holds the OID for Azure TrustedLaunch VMs.
type AzureTrustedLaunch struct{}
@ -117,6 +161,11 @@ func (AzureTrustedLaunch) String() string {
return azureTrustedLaunch
}
// Equal returns true if the other variant is also AzureTrustedLaunch.
func (AzureTrustedLaunch) Equal(other Getter) bool {
return other.OID().Equal(AzureTrustedLaunch{}.OID())
}
// QEMUVTPM holds the QEMUVTPM OID.
type QEMUVTPM struct{}
@ -130,11 +179,7 @@ func (QEMUVTPM) String() string {
return qemuVTPM
}
const (
dummy = "dummy"
awsNitroTPM = "aws-nitro-tpm"
gcpSEVES = "gcp-sev-es"
azureSEVSNP = "azure-sev-snp"
azureTrustedLaunch = "azure-trustedlaunch"
qemuVTPM = "qemu-vtpm"
)
// Equal returns true if the other variant is also QEMUVTPM.
func (QEMUVTPM) Equal(other Getter) bool {
return other.OID().Equal(QEMUVTPM{}.OID())
}

View File

@ -73,21 +73,21 @@ const (
// KonnectivityServerImage server image for konnectivity service.
KonnectivityServerImage = "registry.k8s.io/kas-network-proxy/proxy-server:v0.1.2@sha256:79933c3779bc30e33bb7509dff913e70f6ba78ad441f4827f0f3e840ce5f3ddb" // renovate:container
// JoinImage image of Constellation join service.
JoinImage = "ghcr.io/edgelesssys/constellation/join-service:v2.7.0-pre.0.20230322165747-0a190c2bf672@sha256:d18a79b34744e8a9ca4c95bedd76a95ba642ecf7dc036232b77c7637d077c8bd" // renovate:container
JoinImage = "ghcr.io/edgelesssys/constellation/join-service:v2.7.0-pre.0.20230327112339-ac010f85f74f@sha256:7665a67f3c097a882763d6036a4ffdafe152a43862448e7103fb4a9679fe5946" // renovate:container
// KeyServiceImage image of Constellation KMS server.
KeyServiceImage = "ghcr.io/edgelesssys/constellation/key-service:v2.7.0-pre.0.20230322165747-0a190c2bf672@sha256:0596531339f29d25084857c0378d69c3b098b33ef463a75ec4368eb43ea9970f" // renovate:container
KeyServiceImage = "ghcr.io/edgelesssys/constellation/key-service:v2.7.0-pre.0.20230323170849-e7fc541a5760@sha256:d2e87b4bccf8b07f9c4778d40ffb78c0c99c58156d628052598ee6ba154e6215" // renovate:container
// VerificationImage image of Constellation verification service.
VerificationImage = "ghcr.io/edgelesssys/constellation/verification-service:v2.7.0-pre.0.20230322165747-0a190c2bf672@sha256:8b4fb92d3abbc4b16ce2fe9bd5a597ac83843683dfc912c421365403d421a0ba" // renovate:container
VerificationImage = "ghcr.io/edgelesssys/constellation/verification-service:v2.7.0-pre.0.20230327112339-ac010f85f74f@sha256:6dbb75fa643d044a65abff7857151e727c1967440e2bc46312191200e982733b" // renovate:container
// GcpGuestImage image for GCP guest agent.
// Check for new versions at https://github.com/GoogleCloudPlatform/guest-agent/releases and update in /.github/workflows/build-gcp-guest-agent.yml.
GcpGuestImage = "ghcr.io/edgelesssys/gcp-guest-agent:20230221.0@sha256:8be328a5d8d601170b82481d413cf326b20c5219c016633f1651e35d95f1d6f1" // renovate:container
// ConstellationOperatorImage is the image for the constellation node operator.
ConstellationOperatorImage = "ghcr.io/edgelesssys/constellation/node-operator:v2.7.0-pre.0.20230322165747-0a190c2bf672@sha256:e9c40180be883b5c3d3bf084378d15e89751cee1cce3829914e320cd101e65f6" // renovate:container
ConstellationOperatorImage = "ghcr.io/edgelesssys/constellation/node-operator:v2.7.0-pre.0.20230324160839-da4e2521a9cd@sha256:ea1c351907e9ce989e63bd636a0b1fd090f8d496d80f471d859d49999f7439b4" // renovate:container
// NodeMaintenanceOperatorImage is the image for the node maintenance operator.
NodeMaintenanceOperatorImage = "quay.io/medik8s/node-maintenance-operator:v0.14.0@sha256:2dffb6ffdbbe997d317799fc709baf030d678bde0be0264931ff6b3e94fd89ab" // renovate:container
// QEMUMetadataImage image of QEMU metadata api service.
QEMUMetadataImage = "ghcr.io/edgelesssys/constellation/qemu-metadata-api:v2.7.0-pre.0.20230322165747-0a190c2bf672@sha256:2b7fa64d10fb35e7a1692d53722fce769720521f0c8ffc62bd763575274a29f6" // renovate:container
QEMUMetadataImage = "ghcr.io/edgelesssys/constellation/qemu-metadata-api:v2.7.0-pre.0.20230323135738-c057fac31544@sha256:dfbc53f08669402d40290b073b45e0b8ba43cea5ced8ea58ecf4b43615c96c6b" // renovate:container
// LibvirtImage image that provides libvirt.
LibvirtImage = "ghcr.io/edgelesssys/constellation/libvirt:v2.7.0-pre.0.20230322165747-0a190c2bf672@sha256:3004f83bc7f62cf7c5f44406a4a81c4a59da2db499e91cef1f2490adc3a6261c" // renovate:container

View File

@ -17,7 +17,7 @@ go_library(
"//internal/constants",
"//internal/file",
"//internal/logger",
"//internal/oid",
"//internal/variant",
"@com_github_fsnotify_fsnotify//:fsnotify",
"@com_github_spf13_afero//:afero",
"@org_uber_go_zap//:zap",
@ -39,7 +39,7 @@ go_test(
"//internal/constants",
"//internal/file",
"//internal/logger",
"//internal/oid",
"//internal/variant",
"@com_github_fsnotify_fsnotify//:fsnotify",
"@com_github_spf13_afero//:afero",
"@com_github_stretchr_testify//assert",

View File

@ -7,6 +7,7 @@ SPDX-License-Identifier: AGPL-3.0-only
package watcher
import (
"context"
"encoding/asn1"
"encoding/json"
"errors"
@ -21,7 +22,7 @@ import (
"github.com/edgelesssys/constellation/v2/internal/constants"
"github.com/edgelesssys/constellation/v2/internal/file"
"github.com/edgelesssys/constellation/v2/internal/logger"
"github.com/edgelesssys/constellation/v2/internal/oid"
"github.com/edgelesssys/constellation/v2/internal/variant"
"github.com/spf13/afero"
)
@ -30,12 +31,12 @@ type Updatable struct {
log *logger.Logger
mux sync.Mutex
fileHandler file.Handler
variant oid.Getter
variant variant.Variant
atls.Validator
}
// NewValidator initializes a new updatable validator.
func NewValidator(log *logger.Logger, variant oid.Getter, fileHandler file.Handler) (*Updatable, error) {
func NewValidator(log *logger.Logger, variant variant.Variant, fileHandler file.Handler) (*Updatable, error) {
u := &Updatable{
log: log,
fileHandler: fileHandler,
@ -49,10 +50,10 @@ func NewValidator(log *logger.Logger, variant oid.Getter, fileHandler file.Handl
}
// Validate calls the validators Validate method, and prevents any updates during the call.
func (u *Updatable) Validate(attDoc []byte, nonce []byte) ([]byte, error) {
func (u *Updatable) Validate(ctx context.Context, attDoc []byte, nonce []byte) ([]byte, error) {
u.mux.Lock()
defer u.mux.Unlock()
return u.Validator.Validate(attDoc, nonce)
return u.Validator.Validate(ctx, attDoc, nonce)
}
// OID returns the validators Object Identifier.
@ -77,7 +78,7 @@ func (u *Updatable) Update() error {
// Read ID Key config
var idKeyCfg idkeydigest.Config
if u.variant.OID().Equal(oid.AzureSEVSNP{}.OID()) {
if u.variant.Equal(variant.AzureSEVSNP{}) {
u.log.Infof("Updating SEV-SNP ID Key config")
err := u.fileHandler.ReadJSON(filepath.Join(constants.ServiceBasePath, constants.IDKeyConfigFilename), &idKeyCfg)

View File

@ -24,7 +24,7 @@ import (
"github.com/edgelesssys/constellation/v2/internal/constants"
"github.com/edgelesssys/constellation/v2/internal/file"
"github.com/edgelesssys/constellation/v2/internal/logger"
"github.com/edgelesssys/constellation/v2/internal/oid"
"github.com/edgelesssys/constellation/v2/internal/variant"
"github.com/spf13/afero"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
@ -40,24 +40,24 @@ func TestMain(m *testing.M) {
func TestNewUpdateableValidator(t *testing.T) {
testCases := map[string]struct {
variant oid.Getter
variant variant.Variant
writeFile bool
wantErr bool
}{
"azure": {
variant: oid.AzureSEVSNP{},
variant: variant.AzureSEVSNP{},
writeFile: true,
},
"gcp": {
variant: oid.GCPSEVES{},
variant: variant.GCPSEVES{},
writeFile: true,
},
"qemu": {
variant: oid.QEMUVTPM{},
variant: variant.QEMUVTPM{},
writeFile: true,
},
"no file": {
variant: oid.AzureSEVSNP{},
variant: variant.AzureSEVSNP{},
writeFile: false,
wantErr: true,
},
@ -112,7 +112,7 @@ func TestUpdate(t *testing.T) {
// create server
validator := &Updatable{
log: logger.NewTest(t),
variant: oid.Dummy{},
variant: variant.Dummy{},
fileHandler: handler,
}
@ -146,7 +146,7 @@ func TestUpdate(t *testing.T) {
defer server.Close()
// test connection to server
clientOID := oid.Dummy{}
clientOID := variant.Dummy{}
resp, err := testConnection(require, server.URL, clientOID)
require.NoError(err)
defer resp.Body.Close()
@ -155,7 +155,7 @@ func TestUpdate(t *testing.T) {
assert.EqualValues("hello", body)
// update the server's validator
validator.variant = oid.QEMUVTPM{}
validator.variant = variant.QEMUVTPM{}
require.NoError(validator.Update())
// client connection should fail now, since the server's validator expects a different OID from the client
@ -198,7 +198,7 @@ func TestOIDConcurrency(t *testing.T) {
// create server
validator := &Updatable{
log: logger.NewTest(t),
variant: oid.Dummy{},
variant: variant.Dummy{},
fileHandler: handler,
}
@ -228,7 +228,7 @@ func TestUpdateConcurrency(t *testing.T) {
validator := &Updatable{
log: logger.NewTest(t),
fileHandler: handler,
variant: oid.Dummy{},
variant: variant.Dummy{},
}
require.NoError(handler.WriteJSON(
filepath.Join(constants.ServiceBasePath, constants.MeasurementsFilename),
@ -256,7 +256,7 @@ func TestUpdateConcurrency(t *testing.T) {
wg.Wait()
}
func testConnection(require *require.Assertions, url string, oid oid.Getter) (*http.Response, error) {
func testConnection(require *require.Assertions, url string, oid variant.Getter) (*http.Response, error) {
clientConfig, err := atls.CreateAttestationClientTLSConfig(fakeIssuer{oid}, nil)
require.NoError(err)
client := http.Client{Transport: &http.Transport{TLSClientConfig: clientConfig}}
@ -267,10 +267,10 @@ func testConnection(require *require.Assertions, url string, oid oid.Getter) (*h
}
type fakeIssuer struct {
oid.Getter
variant.Getter
}
func (fakeIssuer) Issue(userData []byte, nonce []byte) ([]byte, error) {
func (fakeIssuer) Issue(_ context.Context, userData []byte, nonce []byte) ([]byte, error) {
return json.Marshal(fakeDoc{UserData: userData, Nonce: nonce})
}
@ -280,6 +280,14 @@ func (o fakeOID) OID() asn1.ObjectIdentifier {
return asn1.ObjectIdentifier(o)
}
func (o fakeOID) String() string {
return o.OID().String()
}
func (o fakeOID) Equal(other variant.Getter) bool {
return o.OID().Equal(other.OID())
}
type fakeDoc struct {
UserData []byte
Nonce []byte

View File

@ -26,6 +26,6 @@ ARG PROJECT_VERSION=0.0.0
RUN --mount=type=cache,target=/root/.cache/go-build CGO_ENABLED=0 go build -o join-service -trimpath -buildvcs=false -ldflags "-s -w -buildid='' -X github.com/edgelesssys/constellation/v2/internal/constants.versionInfo=${PROJECT_VERSION}" ./cmd/
# Use gcr.io/distroless/static here since we need CA certificates to be installed for aTLS operations on GCP.
FROM gcr.io/distroless/static@sha256:1268080dc80a2097c6c273ac501d6ddaf9aaf92de131a2bdb40e0226fb561d00 as release
FROM gcr.io/distroless/static@sha256:8d4cc4a622ce09a75bd7b1eea695008bdbff9e91fea426c2d353ea127dcdc9e3 as release
COPY --from=build /constellation/joinservice/join-service /joinservice
ENTRYPOINT [ "/joinservice" ]

View File

@ -18,7 +18,7 @@ go_library(
"//internal/file",
"//internal/grpc/atlscredentials",
"//internal/logger",
"//internal/oid",
"//internal/variant",
"//internal/watcher",
"//joinservice/internal/kms",
"//joinservice/internal/kubeadm",

View File

@ -27,7 +27,7 @@ import (
"github.com/edgelesssys/constellation/v2/internal/file"
"github.com/edgelesssys/constellation/v2/internal/grpc/atlscredentials"
"github.com/edgelesssys/constellation/v2/internal/logger"
"github.com/edgelesssys/constellation/v2/internal/oid"
"github.com/edgelesssys/constellation/v2/internal/variant"
"github.com/edgelesssys/constellation/v2/internal/watcher"
"github.com/edgelesssys/constellation/v2/joinservice/internal/kms"
"github.com/edgelesssys/constellation/v2/joinservice/internal/kubeadm"
@ -56,7 +56,7 @@ func main() {
handler := file.NewHandler(afero.NewOsFs())
variant, err := oid.FromString(*attestationVariant)
variant, err := variant.FromString(*attestationVariant)
if err != nil {
log.With(zap.Error(err)).Fatalf("Failed to parse attestation variant")
}

View File

@ -26,6 +26,6 @@ WORKDIR /constellation/keyservice/cmd
ARG PROJECT_VERSION=0.0.0
RUN --mount=type=cache,target=/root/.cache/go-build CGO_ENABLED=0 go build -o /constellation/build/keyservice -trimpath -buildvcs=false -ldflags "-s -w -buildid='' -X github.com/edgelesssys/constellation/v2/internal/constants.versionInfo=${PROJECT_VERSION}"
FROM gcr.io/distroless/static:nonroot@sha256:ddde70b96543be368208791ad8ddc9b483cbb33a67bce861e73ad519bc0ed616 as release
FROM gcr.io/distroless/static:nonroot@sha256:149531e38c7e4554d4a6725d7d70593ef9f9881358809463800669ac89f3b0ec as release
COPY --from=build /constellation/build/keyservice /keyservice
ENTRYPOINT ["/keyservice"]

View File

@ -9,7 +9,7 @@ go_library(
deps = [
"//internal/constants",
"//internal/logger",
"//internal/oid",
"//internal/variant",
"//measurement-reader/internal/sorted",
"//measurement-reader/internal/tpm",
"@org_uber_go_zap//:zap",

View File

@ -12,7 +12,7 @@ import (
"github.com/edgelesssys/constellation/v2/internal/constants"
"github.com/edgelesssys/constellation/v2/internal/logger"
"github.com/edgelesssys/constellation/v2/internal/oid"
"github.com/edgelesssys/constellation/v2/internal/variant"
"github.com/edgelesssys/constellation/v2/measurement-reader/internal/sorted"
"github.com/edgelesssys/constellation/v2/measurement-reader/internal/tpm"
"go.uber.org/zap"
@ -21,21 +21,21 @@ import (
func main() {
log := logger.New(logger.JSONLog, zapcore.InfoLevel)
variant := os.Getenv(constants.AttestationVariant)
attestationVariant, err := oid.FromString(variant)
variantString := os.Getenv(constants.AttestationVariant)
attestationVariant, err := variant.FromString(variantString)
if err != nil {
log.With(zap.Error(err)).Fatalf("Failed to parse attestation variant")
}
var m []sorted.Measurement
switch attestationVariant {
case oid.AWSNitroTPM{}, oid.AzureSEVSNP{}, oid.AzureTrustedLaunch{}, oid.GCPSEVES{}, oid.QEMUVTPM{}:
case variant.AWSNitroTPM{}, variant.AzureSEVSNP{}, variant.AzureTrustedLaunch{}, variant.GCPSEVES{}, variant.QEMUVTPM{}:
m, err = tpm.Measurements()
if err != nil {
log.With(zap.Error(err)).Fatalf("Failed to read TPM measurements")
}
default:
log.With(zap.String("attestationVariant", variant)).Fatalf("Unsupported attestation variant")
log.With(zap.String("attestationVariant", variantString)).Fatalf("Unsupported attestation variant")
}
fmt.Println("Measurements:")

View File

@ -1,5 +1,5 @@
# Build the manager binary
FROM golang:1.20.2@sha256:bd4a3e7eee6d6ea30b2e27d6c1ac3c56809e78e08c7e44ddf91f8c741091f5ad as builder
FROM golang:1.20.2@sha256:2101aa981e68ab1e06e3d4ac35ae75ed122f0380e5331e3ae4ba7e811bf9d256 as builder
# Download project root dependencies
WORKDIR /workspace
@ -25,7 +25,7 @@ RUN CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -a -o manager main.go
# Use distroless as minimal base image to package the manager binary
# Refer to https://github.com/GoogleContainerTools/distroless for more details
FROM gcr.io/distroless/static:nonroot@sha256:ddde70b96543be368208791ad8ddc9b483cbb33a67bce861e73ad519bc0ed616 as release
FROM gcr.io/distroless/static:nonroot@sha256:149531e38c7e4554d4a6725d7d70593ef9f9881358809463800669ac89f3b0ec as release
WORKDIR /
COPY --from=builder /workspace/operators/constellation-node-operator/manager .
USER 65532:65532

Some files were not shown because too many files have changed in this diff Show More