diff --git a/README.md b/README.md index 325ddb13..8e749a2a 100644 --- a/README.md +++ b/README.md @@ -180,7 +180,8 @@ and manage the Endorsements and Trust Anchors. The API details are documented under [Endorsement Provisioning Interface](https://github.com/veraison/docs/tree/main/api/endorsement-provisioning). This service accept a variety of Endorsement Formats. For now, PSA (Profile 1 & -Profile 2), CCA, TPM and Parsec (CCA and TPM) based Endorsements are supported. +Profile 2), CCA, TPM, Parsec (CCA and TPM) and SEV-SNP based Endorsements are +supported. Refer to [scope](https://github.com/veraison/docs/blob/main/project-overview.md#scope---provisioning) @@ -195,8 +196,8 @@ Attestation Evidence claims. On the back end, it communicates with the Attestation Verification Results, which are then passed to the challenger. This service acts as a frontend for accepting a variety of attestation token -formats. For now, PSA (Profile 1 & Profile 2), CCA and TPM-based attestation -tokens are supported. +formats. For now, PSA (Profile 1 & Profile 2), CCA, SEV-SNP and TPM-based +attestation tokens are supported. The API is based on the Challenge/Response Interaction Models as documented in [challenge-response](https://github.com/veraison/docs/tree/main/api/challenge-response) diff --git a/deployments/rpm/veraison-services.spec.template b/deployments/rpm/veraison-services.spec.template index a0ffac90..115069e3 100644 --- a/deployments/rpm/veraison-services.spec.template +++ b/deployments/rpm/veraison-services.spec.template @@ -88,10 +88,13 @@ cp -a $DEPLOYMENT_DEST/* %{buildroot}/ %attr(0755, %{USERNAME}, %{GROUPNAME}) %{_bindir}/evcli %attr(0755, %{USERNAME}, %{GROUPNAME}) %{_bindir}/pocli %attr(0755, %{USERNAME}, %{GROUPNAME}) %{_bindir}/veraison +%attr(0755, %{USERNAME}, %{GROUPNAME}) %{_bindir}/amd-kds-coserv.plugin %attr(0755, %{USERNAME}, %{GROUPNAME}) %{_bindir}/arm-cca.plugin +%attr(0755, %{USERNAME}, %{GROUPNAME}) %{_bindir}/nvidia-coserv.plugin %attr(0755, %{USERNAME}, %{GROUPNAME}) %{_bindir}/parsec-cca.plugin %attr(0755, %{USERNAME}, %{GROUPNAME}) %{_bindir}/parsec-tpm.plugin %attr(0755, %{USERNAME}, %{GROUPNAME}) %{_bindir}/psa.plugin +%attr(0755, %{USERNAME}, %{GROUPNAME}) %{_bindir}/sevsnp.plugin %attr(0755, %{USERNAME}, %{GROUPNAME}) %{_bindir}/riot.plugin %attr(0755, %{USERNAME}, %{GROUPNAME}) %{_bindir}/tpm-enacttrust.plugin %attr(0755, %{USERNAME}, %{GROUPNAME}) %{_bindir}/management-service diff --git a/go.mod b/go.mod index c0e6c815..15e0e599 100644 --- a/go.mod +++ b/go.mod @@ -23,17 +23,17 @@ require ( github.com/jackc/pgx/v5 v5.6.0 github.com/jellydator/ttlcache/v3 v3.0.0 github.com/json-iterator/go v1.1.12 // indirect - github.com/lestrrat-go/jwx/v2 v2.0.21 + github.com/lestrrat-go/jwx/v2 v2.1.3 github.com/mattn/go-sqlite3 v1.14.14 github.com/mitchellh/mapstructure v1.5.0 github.com/mitchellh/protoc-gen-go-json v1.1.0 github.com/moogar0880/problems v0.1.1 github.com/open-policy-agent/opa v0.68.0 github.com/petar-dambovaliev/aho-corasick v0.0.0-20211021192214-5ab2d9280aa9 - github.com/spf13/afero v1.11.0 + github.com/spf13/afero v1.12.0 github.com/spf13/jwalterweatherman v1.1.0 github.com/spf13/pflag v1.0.5 - github.com/spf13/viper v1.18.2 + github.com/spf13/viper v1.19.0 github.com/stretchr/testify v1.10.0 github.com/tbaehler/gin-keycloak v1.6.1 github.com/veraison/ccatoken v1.3.2-0.20250512122414-b26aba0635c4 @@ -45,10 +45,10 @@ require ( github.com/veraison/parsec v0.2.1-0.20240912163334-0368b9c16228 github.com/veraison/psatoken v1.2.1-0.20240912124429-aec3ece7886e go.uber.org/zap v1.27.0 - golang.org/x/text v0.22.0 - google.golang.org/grpc v1.66.0 + golang.org/x/text v0.23.0 + google.golang.org/grpc v1.67.3 google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.1.0 - google.golang.org/protobuf v1.34.2 + google.golang.org/protobuf v1.36.4 gopkg.in/go-jose/go-jose.v2 v2.6.3 ) @@ -73,8 +73,8 @@ require ( github.com/chenzhuoyu/base64x v0.0.0-20230717121745-296ad89f973d // indirect github.com/chenzhuoyu/iasm v0.9.0 // indirect github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect - github.com/decred/dcrd/dcrec/secp256k1/v4 v4.2.0 // indirect - github.com/fsnotify/fsnotify v1.7.0 // indirect + github.com/decred/dcrd/dcrec/secp256k1/v4 v4.3.0 // indirect + github.com/fsnotify/fsnotify v1.8.0 // indirect github.com/fxamacker/cbor/v2 v2.8.0 github.com/gabriel-vasile/mimetype v1.4.3 // indirect github.com/gin-contrib/sse v0.1.0 // indirect @@ -85,7 +85,7 @@ require ( github.com/go-playground/universal-translator v0.18.1 // indirect github.com/go-playground/validator/v10 v10.19.0 // indirect github.com/gobwas/glob v0.2.3 // indirect - github.com/goccy/go-json v0.10.2 // indirect + github.com/goccy/go-json v0.10.4 // indirect github.com/golang/glog v1.2.4 // indirect github.com/golang/protobuf v1.5.4 // indirect github.com/gorilla/mux v1.8.1 // indirect @@ -101,58 +101,70 @@ require ( github.com/leodido/go-urn v1.4.0 // indirect github.com/lestrrat-go/blackmagic v1.0.2 // indirect github.com/lestrrat-go/httpcc v1.0.1 // indirect - github.com/lestrrat-go/httprc v1.0.5 // indirect + github.com/lestrrat-go/httprc v1.0.6 // indirect github.com/lestrrat-go/iter v1.0.2 // indirect github.com/lestrrat-go/option v1.0.1 // indirect - github.com/magiconair/properties v1.8.7 // indirect + github.com/magiconair/properties v1.8.9 // indirect github.com/mattn/go-colorable v0.1.13 // indirect - github.com/mattn/go-isatty v0.0.19 // indirect + github.com/mattn/go-isatty v0.0.20 // indirect github.com/mitchellh/go-testing-interface v1.0.0 // indirect github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect github.com/modern-go/reflect2 v1.0.2 // indirect github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect github.com/oklog/run v1.0.0 // indirect github.com/patrickmn/go-cache v2.1.0+incompatible // indirect - github.com/pelletier/go-toml/v2 v2.2.0 // indirect + github.com/pelletier/go-toml/v2 v2.2.3 // indirect github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect github.com/prometheus/client_golang v1.20.2 // indirect github.com/prometheus/client_model v0.6.1 // indirect github.com/prometheus/common v0.55.0 // indirect github.com/prometheus/procfs v0.15.1 // indirect github.com/rcrowley/go-metrics v0.0.0-20200313005456-10cdbea86bc0 // indirect - github.com/sagikazarmark/locafero v0.4.0 // indirect + github.com/sagikazarmark/locafero v0.7.0 // indirect github.com/sagikazarmark/slog-shim v0.1.0 // indirect github.com/segmentio/asm v1.2.0 // indirect github.com/sirupsen/logrus v1.9.3 // indirect github.com/sourcegraph/conc v0.3.0 // indirect - github.com/spf13/cast v1.6.0 // indirect + github.com/spf13/cast v1.7.1 // indirect github.com/subosito/gotenv v1.6.0 // indirect github.com/tchap/go-patricia/v2 v2.3.1 // indirect github.com/twitchyliquid64/golang-asm v0.15.1 // indirect github.com/ugorji/go/codec v1.2.11 // indirect - github.com/veraison/go-cose v1.3.0-rc.1 + github.com/veraison/go-cose v1.3.0 github.com/veraison/swid v1.1.1-0.20230911094910-8ffdd07a22ca github.com/x448/float16 v0.8.4 // indirect github.com/xeipuuv/gojsonpointer v0.0.0-20190905194746-02993c407bfb // indirect github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 // indirect github.com/yashtewari/glob-intersection v0.2.0 // indirect - go.opentelemetry.io/otel v1.28.0 // indirect - go.opentelemetry.io/otel/metric v1.28.0 // indirect - go.opentelemetry.io/otel/sdk v1.28.0 // indirect - go.opentelemetry.io/otel/trace v1.28.0 // indirect - go.uber.org/multierr v1.10.0 // indirect + go.opentelemetry.io/otel v1.29.0 // indirect + go.opentelemetry.io/otel/metric v1.29.0 // indirect + go.opentelemetry.io/otel/sdk v1.29.0 // indirect + go.opentelemetry.io/otel/trace v1.29.0 // indirect + go.uber.org/multierr v1.11.0 // indirect golang.org/x/arch v0.7.0 // indirect - golang.org/x/crypto v0.35.0 - golang.org/x/exp v0.0.0-20230905200255-921286631fa9 // indirect - golang.org/x/net v0.33.0 // indirect + golang.org/x/crypto v0.36.0 + golang.org/x/exp v0.0.0-20250106191152-7588d65b2ba8 // indirect + golang.org/x/net v0.38.0 // indirect golang.org/x/oauth2 v0.27.0 // indirect - golang.org/x/sync v0.11.0 // indirect - golang.org/x/sys v0.30.0 // indirect - google.golang.org/genproto/googleapis/rpc v0.0.0-20240701130421-f6361c86f094 // indirect + golang.org/x/sync v0.12.0 // indirect + golang.org/x/sys v0.31.0 // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20250204164813-702378808489 // indirect gopkg.in/ini.v1 v1.67.0 // indirect gopkg.in/yaml.v2 v2.4.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect sigs.k8s.io/yaml v1.4.0 // indirect ) -require fortio.org/safecast v1.0.0 // indirect +require ( + github.com/google/go-sev-guest v0.14.1 + github.com/jraman567/go-gen-ref v1.2.3 + github.com/veraison/ratsd v0.0.0-20251002182229-94bebd610d15 +) + +require ( + fortio.org/safecast v1.0.0 // indirect + github.com/google/logger v1.1.1 // indirect + github.com/inconshreveable/mousetrap v1.1.0 // indirect + github.com/spf13/cobra v1.8.1 // indirect + github.com/virtee/sev-snp-measure-go v0.0.0-20241128091219-920346c42ecb // indirect +) diff --git a/go.sum b/go.sum index 503cdea4..4d0061c5 100644 --- a/go.sum +++ b/go.sum @@ -714,13 +714,14 @@ github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e/go.mod h1:F5haX7 github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA= github.com/cpuguy83/go-md2man v1.0.10/go.mod h1:SmD6nW6nTyfqj6ABTjUi3V3JVMnlJmwcJI5acqYI6dE= github.com/cpuguy83/go-md2man/v2 v2.0.0/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= +github.com/cpuguy83/go-md2man/v2 v2.0.4/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM= github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/decred/dcrd/dcrec/secp256k1/v4 v4.2.0 h1:8UrgZ3GkP4i/CLijOJx79Yu+etlyjdBU4sfcs2WYQMs= -github.com/decred/dcrd/dcrec/secp256k1/v4 v4.2.0/go.mod h1:v57UDF4pDQJcEfFUCRop3lJL149eHGSe9Jvczhzjo/0= +github.com/decred/dcrd/dcrec/secp256k1/v4 v4.3.0 h1:rpfIENRNNilwHwZeG5+P150SMrnNEcHYvcCuK6dPZSg= +github.com/decred/dcrd/dcrec/secp256k1/v4 v4.3.0/go.mod h1:v57UDF4pDQJcEfFUCRop3lJL149eHGSe9Jvczhzjo/0= github.com/denisbrodbeck/machineid v1.0.1 h1:geKr9qtkB876mXguW2X6TU4ZynleN6ezuMSRhl4D7AQ= github.com/denisbrodbeck/machineid v1.0.1/go.mod h1:dJUwb7PTidGDeYyUBmXZ2GphQBbjJCrnectwCyxcUSI= github.com/dgraph-io/badger/v3 v3.2103.5 h1:ylPa6qzbjYRQMU6jokoj4wzcaweHylt//CH0AKt0akg= @@ -763,8 +764,8 @@ github.com/foxcpp/go-mockdns v1.1.0/go.mod h1:IhLeSFGed3mJIAXPH2aiRQB+kqz7oqu8ld github.com/frankban/quicktest v1.14.6 h1:7Xjx+VpznH+oBnejlPUj8oUpdxnVs4f8XU8WnHkI4W8= github.com/frankban/quicktest v1.14.6/go.mod h1:4ptaffx2x8+WTWXmUCuVU6aPUX1/Mz7zb5vbUoiM6w0= github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= -github.com/fsnotify/fsnotify v1.7.0 h1:8JEhPFa5W2WU7YfeZzPNqzMP6Lwt7L2715Ggo0nosvA= -github.com/fsnotify/fsnotify v1.7.0/go.mod h1:40Bi/Hjc2AVfZrqy+aj+yEI+/bRxZnMJyTJwOpGvigM= +github.com/fsnotify/fsnotify v1.8.0 h1:dAwr6QBTBZIkG8roQaJjGof0pp0EeF+tNV7YBP3F/8M= +github.com/fsnotify/fsnotify v1.8.0/go.mod h1:8jBTzvmWwFyi3Pb8djgCCO5IBqzKJ/Jwo8TRcHyHii0= github.com/fxamacker/cbor/v2 v2.2.0/go.mod h1:TA1xS00nchWmaBnEIxPSE5oHLuJBAVvqrtAnWBwBCVo= github.com/fxamacker/cbor/v2 v2.3.0/go.mod h1:TA1xS00nchWmaBnEIxPSE5oHLuJBAVvqrtAnWBwBCVo= github.com/fxamacker/cbor/v2 v2.8.0 h1:fFtUGXUzXPHTIUdne5+zzMPTfffl3RD5qYnkY40vtxU= @@ -814,8 +815,9 @@ github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/me github.com/gobwas/glob v0.2.3 h1:A4xDbljILXROh+kObIiy5kIaPYD8e96x1tgBhUI5J+Y= github.com/gobwas/glob v0.2.3/go.mod h1:d3Ez4x06l9bZtSvzIay5+Yzi0fmZzPgnTbPcKjJAkT8= github.com/goccy/go-json v0.9.11/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I= -github.com/goccy/go-json v0.10.2 h1:CrxCmQqYDkv1z7lO7Wbh2HN93uovUHgrECaO5ZrCXAU= github.com/goccy/go-json v0.10.2/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I= +github.com/goccy/go-json v0.10.4 h1:JSwxQzIqKfmFX1swYPpUThQZp/Ka4wzJdK0LWVytLPM= +github.com/goccy/go-json v0.10.4/go.mod h1:oq7eo15ShAhp70Anwd5lgX2pLfOS3QCiwU/PULtXL6M= github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zVXpSg4= github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= @@ -887,6 +889,10 @@ github.com/google/go-cmp v0.5.8/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeN github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= +github.com/google/go-configfs-tsm v0.3.2 h1:ZYmHkdQavfsvVGDtX7RRda0gamelUNUhu0A9fbiuLmE= +github.com/google/go-configfs-tsm v0.3.2/go.mod h1:EL1GTDFMb5PZQWDviGfZV9n87WeGTR/JUg13RfwkgRo= +github.com/google/go-sev-guest v0.14.1 h1:j/DXy9jk1qSW/dEV9vDiQnhAVFD1zqnWNVu6p1J0Jgo= +github.com/google/go-sev-guest v0.14.1/go.mod h1:SK9vW+uyfuzYdVN0m8BShL3OQCtXZe/JPF7ZkpD3760= github.com/google/go-tpm v0.1.2-0.20190725015402-ae6dd98980d4/go.mod h1:H9HbmUG2YgV/PHITkO7p6wxEEj/v5nlsVWIwumwH2NI= github.com/google/go-tpm v0.3.0/go.mod h1:iVLWvrPp/bHeEkxTFi9WG6K9w0iy2yIszHwZGHPbzAw= github.com/google/go-tpm v0.3.3 h1:P/ZFNBZYXRxc+z7i5uyd8VP7MaDteuLZInzrH2idRGo= @@ -894,6 +900,8 @@ github.com/google/go-tpm v0.3.3/go.mod h1:9Hyn3rgnzWF9XBWVk6ml6A6hNkbWjNFlDQL51B github.com/google/go-tpm-tools v0.0.0-20190906225433-1614c142f845/go.mod h1:AVfHadzbdzHo54inR2x1v640jdi1YSi3NauM2DUsxk0= github.com/google/go-tpm-tools v0.2.0/go.mod h1:npUd03rQ60lxN7tzeBJreG38RvWwme2N1reF/eeiBk4= github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= +github.com/google/logger v1.1.1 h1:+6Z2geNxc9G+4D4oDO9njjjn2d0wN5d7uOo0vOIW1NQ= +github.com/google/logger v1.1.1/go.mod h1:BkeJZ+1FhQ+/d087r4dzojEg1u2ZX+ZqG1jTUrLM+zQ= github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs= github.com/google/martian/v3 v3.0.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0= github.com/google/martian/v3 v3.1.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0= @@ -971,6 +979,8 @@ github.com/iancoleman/strcase v0.2.0/go.mod h1:iwCmte+B7n89clKwxIoIXy/HfoL7AsD47 github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= +github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8= +github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= github.com/jackc/pgpassfile v1.0.0 h1:/6Hmqy13Ss2zCq62VdNG8tM1wchn8zjSGOBJ6icpsIM= github.com/jackc/pgpassfile v1.0.0/go.mod h1:CEx0iS5ambNFdcRtxPj5JhEz+xB6uRky5eyVu/W2HEg= github.com/jackc/pgservicefile v0.0.0-20221227161230-091c0ba34f0a h1:bbPeKD0xmW/Y25WS6cokEszi5g+S0QxI/d45PkRi7Nk= @@ -984,6 +994,8 @@ github.com/jellydator/ttlcache/v3 v3.0.0/go.mod h1:WwTaEmcXQ3MTjOm4bsZoDFiCu/hMv github.com/jhump/protoreflect v1.6.0 h1:h5jfMVslIg6l29nsMs0D8Wj17RDVdNYti0vDN/PZZoE= github.com/jhump/protoreflect v1.6.0/go.mod h1:eaTn3RZAmMBcV0fifFvlm6VHNz3wSkYyXYWUh7ymB74= github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo= +github.com/jraman567/go-gen-ref v1.2.3 h1:NiPqwWea1eoG6Zn6kSQONdO2F3yrUZX7cmSFZEc0++I= +github.com/jraman567/go-gen-ref v1.2.3/go.mod h1:3uZ9S9s0dPTcq+xdwNVxWrPNuvRepQZW5Xep4cXIB3s= github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM= github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo= github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU= @@ -1026,20 +1038,20 @@ github.com/lestrrat-go/blackmagic v1.0.2 h1:Cg2gVSc9h7sz9NOByczrbUvLopQmXrfFx//N github.com/lestrrat-go/blackmagic v1.0.2/go.mod h1:UrEqBzIR2U6CnzVyUtfM6oZNMt/7O7Vohk2J0OGSAtU= github.com/lestrrat-go/httpcc v1.0.1 h1:ydWCStUeJLkpYyjLDHihupbn2tYmZ7m22BGkcvZZrIE= github.com/lestrrat-go/httpcc v1.0.1/go.mod h1:qiltp3Mt56+55GPVCbTdM9MlqhvzyuL6W/NMDA8vA5E= -github.com/lestrrat-go/httprc v1.0.5 h1:bsTfiH8xaKOJPrg1R+E3iE/AWZr/x0Phj9PBTG/OLUk= -github.com/lestrrat-go/httprc v1.0.5/go.mod h1:mwwz3JMTPBjHUkkDv/IGJ39aALInZLrhBp0X7KGUZlo= +github.com/lestrrat-go/httprc v1.0.6 h1:qgmgIRhpvBqexMJjA/PmwSvhNk679oqD1RbovdCGW8k= +github.com/lestrrat-go/httprc v1.0.6/go.mod h1:mwwz3JMTPBjHUkkDv/IGJ39aALInZLrhBp0X7KGUZlo= github.com/lestrrat-go/iter v1.0.2 h1:gMXo1q4c2pHmC3dn8LzRhJfP1ceCbgSiT9lUydIzltI= github.com/lestrrat-go/iter v1.0.2/go.mod h1:Momfcq3AnRlRjI5b5O8/G5/BvpzrhoFTZcn06fEOPt4= -github.com/lestrrat-go/jwx/v2 v2.0.21 h1:jAPKupy4uHgrHFEdjVjNkUgoBKtVDgrQPB/h55FHrR0= -github.com/lestrrat-go/jwx/v2 v2.0.21/go.mod h1:09mLW8zto6bWL9GbwnqAli+ArLf+5M33QLQPDggkUWM= +github.com/lestrrat-go/jwx/v2 v2.1.3 h1:Ud4lb2QuxRClYAmRleF50KrbKIoM1TddXgBrneT5/Jo= +github.com/lestrrat-go/jwx/v2 v2.1.3/go.mod h1:q6uFgbgZfEmQrfJfrCo90QcQOcXFMfbI/fO0NqRtvZo= github.com/lestrrat-go/option v1.0.1 h1:oAzP2fvZGQKWkvHa1/SAcFolBEca1oN+mQ7eooNBEYU= github.com/lestrrat-go/option v1.0.1/go.mod h1:5ZHFbivi4xwXxhxY9XHDe2FHo6/Z7WWmtT7T5nBBp3I= github.com/lyft/protoc-gen-star v0.6.0/go.mod h1:TGAoBVkt8w7MPG72TrKIu85MIdXwDuzJYeZuUPFPNwA= github.com/lyft/protoc-gen-star v0.6.1/go.mod h1:TGAoBVkt8w7MPG72TrKIu85MIdXwDuzJYeZuUPFPNwA= github.com/lyft/protoc-gen-star/v2 v2.0.1/go.mod h1:RcCdONR2ScXaYnQC5tUzxzlpA3WVYF7/opLeUgcQs/o= github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= -github.com/magiconair/properties v1.8.7 h1:IeQXZAiQcpL9mgcAe1Nu6cX9LLw6ExEHKjN0VQdvPDY= -github.com/magiconair/properties v1.8.7/go.mod h1:Dhd985XPs7jluiymwWYZ0G4Z61jb3vdS329zhj2hYo0= +github.com/magiconair/properties v1.8.9 h1:nWcCbLq1N2v/cpNsy5WvQ37Fb+YElfq20WJ/a8RkpQM= +github.com/magiconair/properties v1.8.9/go.mod h1:Dhd985XPs7jluiymwWYZ0G4Z61jb3vdS329zhj2hYo0= github.com/mattn/go-colorable v0.1.9/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= github.com/mattn/go-colorable v0.1.12/go.mod h1:u5H1YNBxpqRaxsYJYSkiCWKzEfiAb1Gb520KVy5xxl4= github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA= @@ -1047,8 +1059,9 @@ github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovk github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94= github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= -github.com/mattn/go-isatty v0.0.19 h1:JITubQf0MOLdlGRuRq+jtsDlekdYPia9ZFsB8h/APPA= github.com/mattn/go-isatty v0.0.19/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= +github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY= +github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= github.com/mattn/go-sqlite3 v1.14.14 h1:qZgc/Rwetq+MtyE18WhzjokPD93dNqLGNT3QJuLvBGw= github.com/mattn/go-sqlite3 v1.14.14/go.mod h1:NyWgC/yNuGj7Q9rpYnZvas74GogHl5/Z4A/KQRfk6bU= github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= @@ -1083,8 +1096,9 @@ github.com/patrickmn/go-cache v2.1.0+incompatible h1:HRMgzkcYKYpi3C8ajMPV8OFXaaR github.com/patrickmn/go-cache v2.1.0+incompatible/go.mod h1:3Qf8kWWT7OJRJbdiICTKqZju1ZixQ/KpMGzzAfe6+WQ= github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic= github.com/pelletier/go-toml/v2 v2.0.8/go.mod h1:vuYfssBdrU2XDZ9bYydBu6t+6a6PYNcZljzZR9VXg+4= -github.com/pelletier/go-toml/v2 v2.2.0 h1:QLgLl2yMN7N+ruc31VynXs1vhMZa7CeHHejIeBAsoHo= github.com/pelletier/go-toml/v2 v2.2.0/go.mod h1:1t835xjRzz80PqgE6HHgN2JOsmgYu/h4qDAS4n929Rs= +github.com/pelletier/go-toml/v2 v2.2.3 h1:YmeHyLY8mFWbdkNWwpr+qIL2bEqT0o95WSdkNHvL12M= +github.com/pelletier/go-toml/v2 v2.2.3/go.mod h1:MfCQTFTvCcUyyvvwm1+G6H/jORL20Xlb6rzQu9GuUkc= github.com/petar-dambovaliev/aho-corasick v0.0.0-20211021192214-5ab2d9280aa9 h1:lL+y4Xv20pVlCGyLzNHRC0I0rIHhIL1lTvHizoS/dU8= github.com/petar-dambovaliev/aho-corasick v0.0.0-20211021192214-5ab2d9280aa9/go.mod h1:EHPiTAKtiFmrMldLUNswFwfZ2eJIYBHktdaUTZxYWRw= github.com/phpdave11/gofpdf v1.4.2/go.mod h1:zpO6xFn9yxo3YLyMvW8HcKWVdbNqgIfOOp2dXMnm1mY= @@ -1133,10 +1147,11 @@ github.com/rogpeppe/go-internal v1.12.0 h1:exVL4IDcn6na9z1rAb56Vxr+CgyK3nn3O+epU github.com/rogpeppe/go-internal v1.12.0/go.mod h1:E+RYuTGaKKdloAfM02xzb0FW3Paa99yedzYV+kq4uf4= github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g= github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= +github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= github.com/ruudk/golang-pdf417 v0.0.0-20181029194003-1af4ab5afa58/go.mod h1:6lfFZQK844Gfx8o5WFuvpxWRwnSoipWe/p622j1v06w= github.com/ruudk/golang-pdf417 v0.0.0-20201230142125-a7e3863a1245/go.mod h1:pQAZKsJ8yyVxGRWYNEm9oFB8ieLgKFnamEyDmSA0BRk= -github.com/sagikazarmark/locafero v0.4.0 h1:HApY1R9zGo4DBgr7dqsTH/JJxLTTsOt7u6keLGt6kNQ= -github.com/sagikazarmark/locafero v0.4.0/go.mod h1:Pe1W6UlPYUk/+wc/6KFhbORCfqzgYEpgQ3O5fPuL3H4= +github.com/sagikazarmark/locafero v0.7.0 h1:5MqpDsTGNDhY8sGp0Aowyf0qKsPrhewaLSsFaodPcyo= +github.com/sagikazarmark/locafero v0.7.0/go.mod h1:2za3Cg5rMaTMoG/2Ulr9AwtFaIppKXTRYnozin4aB5k= github.com/sagikazarmark/slog-shim v0.1.0 h1:diDBnUNK9N/354PgrxMywXnAwEr1QZcOr6gto+ugjYE= github.com/sagikazarmark/slog-shim v0.1.0/go.mod h1:SrcSrq8aKtyuqEI1uvTDTK1arOWRIczQRv+GVI1AkeQ= github.com/segmentio/asm v1.2.0 h1:9BQrFxC+YOHJlTlHGkTrFWf59nbL3XnCoFLTwDCI7ys= @@ -1153,13 +1168,15 @@ github.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B github.com/spf13/afero v1.3.3/go.mod h1:5KUK8ByomD5Ti5Artl0RtHeI5pTF7MIDuXL3yY520V4= github.com/spf13/afero v1.6.0/go.mod h1:Ai8FlHk4v/PARR026UzYexafAt9roJ7LcLMAmO6Z93I= github.com/spf13/afero v1.9.2/go.mod h1:iUV7ddyEEZPO5gA3zD4fJt6iStLlL+Lg4m2cihcDf8Y= -github.com/spf13/afero v1.11.0 h1:WJQKhtpdm3v2IzqG8VMqrr6Rf3UYpEF239Jy9wNepM8= -github.com/spf13/afero v1.11.0/go.mod h1:GH9Y3pIexgf1MTIWtNGyogA5MwRIDXGUr+hbWNoBjkY= +github.com/spf13/afero v1.12.0 h1:UcOPyRBYczmFn6yvphxkn9ZEOY65cpwGKb5mL36mrqs= +github.com/spf13/afero v1.12.0/go.mod h1:ZTlWwG4/ahT8W7T0WQ5uYmjI9duaLQGy3Q2OAl4sk/4= github.com/spf13/cast v1.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE= -github.com/spf13/cast v1.6.0 h1:GEiTHELF+vaR5dhz3VqZfFSzZjYbgeKDpBxQVS4GYJ0= -github.com/spf13/cast v1.6.0/go.mod h1:ancEpBxwJDODSW/UG4rDrAqiKolqNNh2DX3mk86cAdo= +github.com/spf13/cast v1.7.1 h1:cuNEagBQEHWN1FnbGEjCXL2szYEXqfJPbP2HNUaca9Y= +github.com/spf13/cast v1.7.1/go.mod h1:ancEpBxwJDODSW/UG4rDrAqiKolqNNh2DX3mk86cAdo= github.com/spf13/cobra v0.0.5/go.mod h1:3K3wKZymM7VvHMDS9+Akkh4K60UwM26emMESw8tLCHU= github.com/spf13/cobra v1.0.0/go.mod h1:/6GTrnGXV9HjY+aR4k0oJ5tcvakLuG6EuKReYlHNrgE= +github.com/spf13/cobra v1.8.1 h1:e5/vxKd/rZsfSJMUX1agtjeTDf+qv1/JdBF8gg5k9ZM= +github.com/spf13/cobra v1.8.1/go.mod h1:wHxEcudfqmLYa8iTfL+OuZPbBZkmvliBWKIezN3kD9Y= github.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo= github.com/spf13/jwalterweatherman v1.1.0 h1:ue6voC5bR5F8YxI5S67j9i582FU4Qvo2bmqnqMYADFk= github.com/spf13/jwalterweatherman v1.1.0/go.mod h1:aNWZUN0dPAAO/Ljvb5BEdw96iTZ0EXowPYD95IqWIGo= @@ -1168,8 +1185,8 @@ github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= github.com/spf13/viper v1.3.2/go.mod h1:ZiWeW+zYFKm7srdB9IoDzzZXaJaI5eL9QjNiN/DMA2s= github.com/spf13/viper v1.4.0/go.mod h1:PTJ7Z/lr49W6bUbkmS1V3by4uWynFiR9p7+dSq/yZzE= -github.com/spf13/viper v1.18.2 h1:LUXCnvUvSM6FXAsj6nnfc8Q2tp1dIgUfY9Kc8GsSOiQ= -github.com/spf13/viper v1.18.2/go.mod h1:EKmWIqdnk5lOcmR72yw6hS+8OPYcwD0jteitLMVB+yk= +github.com/spf13/viper v1.19.0 h1:RWq5SEjt8o25SROyN3z2OrDB9l7RPd3lwTWU8EcEdcI= +github.com/spf13/viper v1.19.0/go.mod h1:GQUN9bilAbhU/jgc1bKs99f/suXKeUMct8Adx5+Ntkg= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= @@ -1216,14 +1233,18 @@ github.com/veraison/ear v1.1.2 h1:Xs41FqAG8IyJaceqNFcX2+nf51Et1uyhmCJV8SZqw/8= github.com/veraison/ear v1.1.2/go.mod h1:O3yKgZR04DWKHHiNxfXCMX9ky0cLVoC67TFks6JwEhI= github.com/veraison/eat v0.0.0-20220117140849-ddaf59d69f53 h1:5gnX2TrGd/Xz8DOp2OaLtg/jLoIubSUTrgz6iZ58pJ4= github.com/veraison/eat v0.0.0-20220117140849-ddaf59d69f53/go.mod h1:+kxt8iuFiVvKRs2VQ1Ho7bbAScXAB/kHFFuP5Biw19I= -github.com/veraison/go-cose v1.3.0-rc.1 h1:j7mMBdwkbq4c+pgEZVbbWG8UwVIgGHPp6+TAAYJj+UY= -github.com/veraison/go-cose v1.3.0-rc.1/go.mod h1:df09OV91aHoQWLmy1KsDdYiagtXgyAwAl8vFeFn1gMc= +github.com/veraison/go-cose v1.3.0 h1:2/H5w8kdSpQJyVtIhx8gmwPJ2uSz1PkyWFx0idbd7rk= +github.com/veraison/go-cose v1.3.0/go.mod h1:df09OV91aHoQWLmy1KsDdYiagtXgyAwAl8vFeFn1gMc= github.com/veraison/parsec v0.2.1-0.20240912163334-0368b9c16228 h1:oMCBfNZ8yxeMHelMg/H8uLrBLRvipjAwBL0d5/F9bvY= github.com/veraison/parsec v0.2.1-0.20240912163334-0368b9c16228/go.mod h1:hobpAGxGmjCyluLHTNMdgJYficPXno4HZWKJSuUwZ7w= github.com/veraison/psatoken v1.2.1-0.20240912124429-aec3ece7886e h1:W1OWcrRvfN0EWyldcpFgwl9xdKBbZUlk5pnbLTcR8Ec= github.com/veraison/psatoken v1.2.1-0.20240912124429-aec3ece7886e/go.mod h1:bXUwdYAGcRoclxe73JmO8Z9ngV9KDHqW20afM9Q0FKo= +github.com/veraison/ratsd v0.0.0-20251002182229-94bebd610d15 h1:7oo/WsvzHgm54FtzMq5g4GzU2dZmEJUQ21wPrSarNxQ= +github.com/veraison/ratsd v0.0.0-20251002182229-94bebd610d15/go.mod h1:RFQMnjXCJVqc8V33F4BCAE76E0fjHS+4b+JkCAlUiJk= github.com/veraison/swid v1.1.1-0.20230911094910-8ffdd07a22ca h1:osmCKwWO/xM68Kz+rIXio1DNzEY2NdJOpGpoy5r8NlE= github.com/veraison/swid v1.1.1-0.20230911094910-8ffdd07a22ca/go.mod h1:d5jt76uMNbTfQ+f2qU4Lt8RvWOTsv6PFgstIM1QdMH0= +github.com/virtee/sev-snp-measure-go v0.0.0-20241128091219-920346c42ecb h1:iBPEloogBk7uK2Ygtz1l6gJabikXs8ASZCmormbn2lM= +github.com/virtee/sev-snp-measure-go v0.0.0-20241128091219-920346c42ecb/go.mod h1:dEkBe8JnxU5itNjZDEQINFd7f7l4DtjfqRuzPQcit4w= github.com/x448/float16 v0.8.4 h1:qLwI1I70+NjRFUR3zs1JPUCgaCXSh3SW62uAKT1mSBM= github.com/x448/float16 v0.8.4/go.mod h1:14CWIYCyZA/cWjXOioeEpHeN/83MdbZDRQHoFcYsOfg= github.com/xeipuuv/gojsonpointer v0.0.0-20190905194746-02993c407bfb h1:zGWFAtiMcyryUHoUjUJX0/lt1H2+i2Ka2n+D3DImSNo= @@ -1253,20 +1274,20 @@ go.opencensus.io v0.22.5/go.mod h1:5pWMHQbX5EPX2/62yrJeAkowc+lfs/XD7Uxpq3pI6kk= go.opencensus.io v0.23.0/go.mod h1:XItmlyltB5F7CS4xOC1DcqMoFqwtC6OG2xF7mCv7P7E= go.opencensus.io v0.24.0 h1:y73uSU6J157QMP2kn2r30vwW1A2W2WFwSCGnAVxeaD0= go.opencensus.io v0.24.0/go.mod h1:vNK8G9p7aAivkbmorf4v+7Hgx+Zs0yY+0fOtgBfjQKo= -go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.53.0 h1:4K4tsIXefpVJtvA/8srF4V4y0akAoPHkIslgAkjixJA= -go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.53.0/go.mod h1:jjdQuTGVsXV4vSs+CJ2qYDeDPf9yIJV23qlIzBm73Vg= -go.opentelemetry.io/otel v1.28.0 h1:/SqNcYk+idO0CxKEUOtKQClMK/MimZihKYMruSMViUo= -go.opentelemetry.io/otel v1.28.0/go.mod h1:q68ijF8Fc8CnMHKyzqL6akLO46ePnjkgfIMIjUIX9z4= +go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.54.0 h1:TT4fX+nBOA/+LUkobKGW1ydGcn+G3vRw9+g5HwCphpk= +go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.54.0/go.mod h1:L7UH0GbB0p47T4Rri3uHjbpCFYrVrwc1I25QhNPiGK8= +go.opentelemetry.io/otel v1.29.0 h1:PdomN/Al4q/lN6iBJEN3AwPvUiHPMlt93c8bqTG5Llw= +go.opentelemetry.io/otel v1.29.0/go.mod h1:N/WtXPs1CNCUEx+Agz5uouwCba+i+bJGFicT8SR4NP8= go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.28.0 h1:3Q/xZUyC1BBkualc9ROb4G8qkH90LXEIICcs5zv1OYY= go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.28.0/go.mod h1:s75jGIWA9OfCMzF0xr+ZgfrB5FEbbV7UuYo32ahUiFI= go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.28.0 h1:R3X6ZXmNPRR8ul6i3WgFURCHzaXjHdm0karRG/+dj3s= go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.28.0/go.mod h1:QWFXnDavXWwMx2EEcZsf3yxgEKAqsxQ+Syjp+seyInw= -go.opentelemetry.io/otel/metric v1.28.0 h1:f0HGvSl1KRAU1DLgLGFjrwVyismPlnuU6JD6bOeuA5Q= -go.opentelemetry.io/otel/metric v1.28.0/go.mod h1:Fb1eVBFZmLVTMb6PPohq3TO9IIhUisDsbJoL/+uQW4s= -go.opentelemetry.io/otel/sdk v1.28.0 h1:b9d7hIry8yZsgtbmM0DKyPWMMUMlK9NEKuIG4aBqWyE= -go.opentelemetry.io/otel/sdk v1.28.0/go.mod h1:oYj7ClPUA7Iw3m+r7GeEjz0qckQRJK2B8zjcZEfu7Pg= -go.opentelemetry.io/otel/trace v1.28.0 h1:GhQ9cUuQGmNDd5BTCP2dAvv75RdMxEfTmYejp+lkx9g= -go.opentelemetry.io/otel/trace v1.28.0/go.mod h1:jPyXzNPg6da9+38HEwElrQiHlVMTnVfM3/yv2OlIHaI= +go.opentelemetry.io/otel/metric v1.29.0 h1:vPf/HFWTNkPu1aYeIsc98l4ktOQaL6LeSoeV2g+8YLc= +go.opentelemetry.io/otel/metric v1.29.0/go.mod h1:auu/QWieFVWx+DmQOUMgj0F8LHWdgalxXqvp7BII/W8= +go.opentelemetry.io/otel/sdk v1.29.0 h1:vkqKjk7gwhS8VaWb0POZKmIEDimRCMsopNYnriHyryo= +go.opentelemetry.io/otel/sdk v1.29.0/go.mod h1:pM8Dx5WKnvxLCb+8lG1PRNIDxu9g9b9g59Qr7hfAAok= +go.opentelemetry.io/otel/trace v1.29.0 h1:J/8ZNK4XgR7a21DZUAsbF8pZ5Jcw1VhACmnYt39JTi4= +go.opentelemetry.io/otel/trace v1.29.0/go.mod h1:eHl3w0sp3paPkYstJOmAimxhiFXPg+MMTlEh3nsQgWQ= go.opentelemetry.io/proto/otlp v0.7.0/go.mod h1:PqfVotwruBrMGOCsRd/89rSnXhoiJIqeYNgFYFoEGnI= go.opentelemetry.io/proto/otlp v0.15.0/go.mod h1:H7XAot3MsfNsj7EXtrA2q5xSNQ10UqI405h3+duxN4U= go.opentelemetry.io/proto/otlp v0.19.0/go.mod h1:H7XAot3MsfNsj7EXtrA2q5xSNQ10UqI405h3+duxN4U= @@ -1276,8 +1297,8 @@ go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto= go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE= go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0= -go.uber.org/multierr v1.10.0 h1:S0h4aNzvfcFsC3dRF1jLoaov7oRaKqRGC/pUEJ2yvPQ= -go.uber.org/multierr v1.10.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y= +go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0= +go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y= go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q= go.uber.org/zap v1.27.0 h1:aJMhYGrd5QSmlpLMr2MftRKl7t8J8PTZPA732ud/XR8= go.uber.org/zap v1.27.0/go.mod h1:GB2qFLM7cTU87MWRP2mPIjqfIDnGu+VIO4V/SdhGo2E= @@ -1302,8 +1323,8 @@ golang.org/x/crypto v0.7.0/go.mod h1:pYwdfH91IfpZVANVyUOhSIPZaFoJGxTFbZhFTx+dXZU golang.org/x/crypto v0.9.0/go.mod h1:yrmDGqONDYtNj3tH8X9dzUun2m2lzPa9ngI6/RUPGR0= golang.org/x/crypto v0.14.0/go.mod h1:MVFd36DqK4CsrnJYDkBA3VC4m2GkXAM0PvzMCn4JQf4= golang.org/x/crypto v0.19.0/go.mod h1:Iy9bg/ha4yyC70EfRS8jz+B6ybOBKMaSxLj6P6oBDfU= -golang.org/x/crypto v0.35.0 h1:b15kiHdrGCHrP6LvwaQ3c03kgNhhiMgvlhxHQhmg2Xs= -golang.org/x/crypto v0.35.0/go.mod h1:dy7dXNW32cAb/6/PRuTNsix8T+vJAqvuIy5Bli/x0YQ= +golang.org/x/crypto v0.36.0 h1:AnAEvhDddvBdpY+uR+MyHmuZzzNqXSe/GvuDeob5L34= +golang.org/x/crypto v0.36.0/go.mod h1:Y4J0ReaxCR1IMaabaSMugxJES1EpwhBHhv2bDHklZvc= golang.org/x/exp v0.0.0-20180321215751-8460e604b9de/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20180807140117-3d87b88a115f/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= @@ -1319,8 +1340,8 @@ golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u0 golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM= golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU= golang.org/x/exp v0.0.0-20220827204233-334a2380cb91/go.mod h1:cyybsKvd6eL0RnXn6p/Grxp8F5bW7iYuBgsNCOHpMYE= -golang.org/x/exp v0.0.0-20230905200255-921286631fa9 h1:GoHiUyI/Tp2nVkLI2mCxVkOjsbSXD66ic0XW0js0R9g= -golang.org/x/exp v0.0.0-20230905200255-921286631fa9/go.mod h1:S2oDrQGGwySpoQPVqRShND87VCbxmc6bL1Yd2oYrm6k= +golang.org/x/exp v0.0.0-20250106191152-7588d65b2ba8 h1:yqrTHse8TCMW1M1ZCP+VAR/l0kKxwaAIqN/il7x4voA= +golang.org/x/exp v0.0.0-20250106191152-7588d65b2ba8/go.mod h1:tujkw807nyEEAamNbDrEGzRav+ilXA7PCRAd6xsmwiU= golang.org/x/image v0.0.0-20180708004352-c73c2afc3b81/go.mod h1:ux5Hcp/YLpHSI86hEcLt0YII63i6oz57MZXIpbrjZUs= 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= @@ -1363,8 +1384,8 @@ golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91 golang.org/x/mod v0.7.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= golang.org/x/mod v0.9.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= -golang.org/x/mod v0.17.0 h1:zY54UmvipHiNd+pm+m0x9KhZ9hl1/7QNMyxXbc6ICqA= -golang.org/x/mod v0.17.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= +golang.org/x/mod v0.22.0 h1:D4nJWe9zXqHOmWqj4VMOJhvzj7bEZg4wEYa759z1pH4= +golang.org/x/mod v0.22.0/go.mod h1:6SkKJ3Xj0I0BrPOZoBy3bdMptDDU9oJrpohJ3eWZ1fY= 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-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -1430,8 +1451,8 @@ golang.org/x/net v0.9.0/go.mod h1:d48xBJpPfHeWQsugry2m+kC02ZBRGRgulfHnEXEuWns= golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg= golang.org/x/net v0.17.0/go.mod h1:NxSsAGuq816PNPmqtQdLE42eU2Fs7NoRIZrHJAlaCOE= golang.org/x/net v0.21.0/go.mod h1:bIjVDfnllIU7BJ2DNgfnXvpSvtn8VRwhlsaeUTyUS44= -golang.org/x/net v0.33.0 h1:74SYHlV8BIgHIFC/LrYkOGIwL19eTYXQ5wc6TBuO36I= -golang.org/x/net v0.33.0/go.mod h1:HXLR5J+9DxmrqMwG9qjGCxZ+zKXxBru04zlTvWlWuN4= +golang.org/x/net v0.38.0 h1:vRMAPTMaeGqVhG5QyLJHqNDwecKTomGeqbnfZyKlBI8= +golang.org/x/net v0.38.0/go.mod h1:ivrbrMbzFq5J41QOQh0siUuly180yBYtLp+CKbEaFx8= 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= @@ -1482,8 +1503,8 @@ golang.org/x/sync v0.0.0-20220819030929-7fc1605a5dde/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.0.0-20220929204114-8fcdb60fdcc0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.2.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.11.0 h1:GGz8+XQP4FvTTrjZPzNKTMFtSXH80RAzG+5ghFPgK9w= -golang.org/x/sync v0.11.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= +golang.org/x/sync v0.12.0 h1:MHc5BpPuC30uJk597Ri8TV3CNZcTLu6B6z4lJy+g6Jw= +golang.org/x/sync v0.12.0/go.mod h1:1dzgHSNfp02xaA81J2MS99Qcpr2w7fw1gpm99rleRqA= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20181107165924-66b7b1311ac8/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= @@ -1529,6 +1550,7 @@ golang.org/x/sys v0.0.0-20210320140829-1e4c9ba3b0c4/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210423185535-09eb48e85fd7/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210426230700-d19ff857e887/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210514084401-e8d321eab015/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210603125802-9665404d3644/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= @@ -1573,8 +1595,8 @@ golang.org/x/sys v0.7.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.13.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.17.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/sys v0.30.0 h1:QjkSwP/36a20jFYWkSue1YwXzLmsV5Gfq7Eiy72C1uc= -golang.org/x/sys v0.30.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.31.0 h1:ioabZlmFYtWhL+TRYpcnNlLwhyxaM9kWTDEmfnprqik= +golang.org/x/sys v0.31.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k= 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= @@ -1605,8 +1627,8 @@ golang.org/x/text v0.8.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= -golang.org/x/text v0.22.0 h1:bofq7m3/HAFvbF51jz3Q9wLg3jkvSPuiZu/pD1XwgtM= -golang.org/x/text v0.22.0/go.mod h1:YRoo4H8PVmsu+E3Ou7cqLVH8oXWIHVoX0jqUWALQhfY= +golang.org/x/text v0.23.0 h1:D71I7dUrlY+VX0gQShAThNGHFxZ13dGLBHQLVl1mJlY= +golang.org/x/text v0.23.0/go.mod h1:/BLNzu4aZCJ1+kcD0DNRotWKage4q2rGVAg4o22unh4= 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= @@ -1675,8 +1697,8 @@ golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc golang.org/x/tools v0.3.0/go.mod h1:/rWhSS2+zyEVwoJf8YAX6L2f0ntZ7Kn/mGgAWcipA5k= golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= golang.org/x/tools v0.7.0/go.mod h1:4pg6aUX35JBAogB10C9AtvVL+qowtN4pT3CGSQex14s= -golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d h1:vU5i/LfpvrRCpgM/VPfJLg5KjxD3E+hfT1SH+d9zLwg= -golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d/go.mod h1:aiJjzUbINMkxbQROHiO6hDPo2LHcIPhhQsa9DLh0yGk= +golang.org/x/tools v0.29.0 h1:Xx0h3TtM9rzQpQuR4dKLrdglAmCEN5Oi+P74JdhdzXE= +golang.org/x/tools v0.29.0/go.mod h1:KMQVMRsVxU6nHCFXrBPhDB8XncLNLM0lIy/F14RP588= 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= @@ -1896,20 +1918,20 @@ google.golang.org/genproto v0.0.0-20230403163135-c38d8f061ccd/go.mod h1:UUQDJDOl google.golang.org/genproto v0.0.0-20230410155749-daa745c078e1/go.mod h1:nKE/iIaLqn2bQwXBg8f1g2Ylh6r5MN5CmZvuzZCgsCU= google.golang.org/genproto v0.0.0-20230525234025-438c736192d0/go.mod h1:9ExIQyXL5hZrHzQceCwuSYwZZ5QZBazOcprJ5rgs3lY= google.golang.org/genproto v0.0.0-20230530153820-e85fd2cbaebc/go.mod h1:xZnkP7mREFX5MORlOPEzLMr+90PPZQ2QWzrVTWfAq64= -google.golang.org/genproto v0.0.0-20231106174013-bbf56f31fb17 h1:wpZ8pe2x1Q3f2KyT5f8oP/fa9rHAKgFPr/HZdNuS+PQ= +google.golang.org/genproto v0.0.0-20241118233622-e639e219e697 h1:ToEetK57OidYuqD4Q5w+vfEnPvPpuTwedCNVohYJfNk= google.golang.org/genproto/googleapis/api v0.0.0-20230525234020-1aefcd67740a/go.mod h1:ts19tUU+Z0ZShN1y3aPyq2+O3d5FUNNgT6FtOzmrNn8= google.golang.org/genproto/googleapis/api v0.0.0-20230525234035-dd9d682886f9/go.mod h1:vHYtlOoi6TsQ3Uk2yxR7NI5z8uoV+3pZtR4jmHIkRig= google.golang.org/genproto/googleapis/api v0.0.0-20230526203410-71b5a4ffd15e/go.mod h1:vHYtlOoi6TsQ3Uk2yxR7NI5z8uoV+3pZtR4jmHIkRig= google.golang.org/genproto/googleapis/api v0.0.0-20230530153820-e85fd2cbaebc/go.mod h1:vHYtlOoi6TsQ3Uk2yxR7NI5z8uoV+3pZtR4jmHIkRig= -google.golang.org/genproto/googleapis/api v0.0.0-20240701130421-f6361c86f094 h1:0+ozOGcrp+Y8Aq8TLNN2Aliibms5LEzsq99ZZmAGYm0= -google.golang.org/genproto/googleapis/api v0.0.0-20240701130421-f6361c86f094/go.mod h1:fJ/e3If/Q67Mj99hin0hMhiNyCRmt6BQ2aWIJshUSJw= +google.golang.org/genproto/googleapis/api v0.0.0-20241209162323-e6fa225c2576 h1:CkkIfIt50+lT6NHAVoRYEyAvQGFM7xEwXUUywFvEb3Q= +google.golang.org/genproto/googleapis/api v0.0.0-20241209162323-e6fa225c2576/go.mod h1:1R3kvZ1dtP3+4p4d3G8uJ8rFk/fWlScl38vanWACI08= google.golang.org/genproto/googleapis/bytestream v0.0.0-20230530153820-e85fd2cbaebc/go.mod h1:ylj+BE99M198VPbBh6A8d9n3w8fChvyLK3wwBOjXBFA= google.golang.org/genproto/googleapis/rpc v0.0.0-20230525234015-3fc162c6f38a/go.mod h1:xURIpW9ES5+/GZhnV6beoEtxQrnkRGIfP5VQG2tCBLc= google.golang.org/genproto/googleapis/rpc v0.0.0-20230525234030-28d5490b6b19/go.mod h1:66JfowdXAEgad5O9NnYcsNPLCPZJD++2L9X0PCMODrA= google.golang.org/genproto/googleapis/rpc v0.0.0-20230526203410-71b5a4ffd15e/go.mod h1:66JfowdXAEgad5O9NnYcsNPLCPZJD++2L9X0PCMODrA= google.golang.org/genproto/googleapis/rpc v0.0.0-20230530153820-e85fd2cbaebc/go.mod h1:66JfowdXAEgad5O9NnYcsNPLCPZJD++2L9X0PCMODrA= -google.golang.org/genproto/googleapis/rpc v0.0.0-20240701130421-f6361c86f094 h1:BwIjyKYGsK9dMCBOorzRri8MQwmi7mT9rGHsCEinZkA= -google.golang.org/genproto/googleapis/rpc v0.0.0-20240701130421-f6361c86f094/go.mod h1:Ue6ibwXGpU+dqIcODieyLOcgj7z8+IcskoNIgZxtrFY= +google.golang.org/genproto/googleapis/rpc v0.0.0-20250204164813-702378808489 h1:5bKytslY8ViY0Cj/ewmRtrWHW64bNF03cAatUUFCdFI= +google.golang.org/genproto/googleapis/rpc v0.0.0-20250204164813-702378808489/go.mod h1:8BS3B93F/U1juMFq9+EDk+qOT5CO1R9IzXxG3PTqiRk= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38= google.golang.org/grpc v1.21.0/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM= @@ -1952,8 +1974,8 @@ google.golang.org/grpc v1.52.0/go.mod h1:pu6fVzoFb+NBYNAvQL08ic+lvB2IojljRYuun5v google.golang.org/grpc v1.53.0/go.mod h1:OnIrk0ipVdj4N5d9IUoFUx72/VlD7+jUsHwZgwSMQpw= google.golang.org/grpc v1.54.0/go.mod h1:PUSEXI6iWghWaB6lXM4knEgpJNu2qUcKfDtNci3EC2g= google.golang.org/grpc v1.55.0/go.mod h1:iYEXKGkEBhg1PjZQvoYEVPTDkHo1/bjTnfwTeGONTY8= -google.golang.org/grpc v1.66.0 h1:DibZuoBznOxbDQxRINckZcUvnCEvrW9pcWIE2yF9r1c= -google.golang.org/grpc v1.66.0/go.mod h1:s3/l6xSSCURdVfAnL+TqCNMyTDAGN6+lZeVxnZR128Y= +google.golang.org/grpc v1.67.3 h1:OgPcDAFKHnH8X3O4WcO4XUc8GRDeKsKReqbQtiCj7N8= +google.golang.org/grpc v1.67.3/go.mod h1:YGaHCc6Oap+FzBJTZLBzkGSYt/cvGPFTPxkn7QfSU8s= google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.1.0 h1:M1YKkFIboKNieVO5DLUEVzQfGwJD30Nv2jfUgzb5UcE= google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.1.0/go.mod h1:6Kw0yEErY5E/yWrBtf03jp27GLLJujG4z/JK95pnjjw= google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= @@ -1974,8 +1996,8 @@ google.golang.org/protobuf v1.28.1/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqw google.golang.org/protobuf v1.29.1/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= google.golang.org/protobuf v1.30.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= google.golang.org/protobuf v1.31.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= -google.golang.org/protobuf v1.34.2 h1:6xV6lTsCfpGD21XK49h7MhtcApnLqkfYgPcdHftf6hg= -google.golang.org/protobuf v1.34.2/go.mod h1:qYOHts0dSfpeUzUFpOMr/WGzszTmLH+DiWniOlNbLDw= +google.golang.org/protobuf v1.36.4 h1:6A3ZDJHn/eNqc1i+IdefRzy/9PokBTPvcqMySR7NNIM= +google.golang.org/protobuf v1.36.4/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE= gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= diff --git a/scheme/Makefile b/scheme/Makefile index 3d8709b2..9ebb1207 100644 --- a/scheme/Makefile +++ b/scheme/Makefile @@ -10,6 +10,7 @@ SUBDIR += parsec-tpm SUBDIR += parsec-cca SUBDIR += nvidia-coserv SUBDIR += amd-kds-coserv +SUBDIR += sevsnp clean: ; $(RM) -rf ./bin diff --git a/scheme/sevsnp/Makefile b/scheme/sevsnp/Makefile new file mode 100644 index 00000000..68ba5f08 --- /dev/null +++ b/scheme/sevsnp/Makefile @@ -0,0 +1,14 @@ +# Copyright 2025 Contributors to the Veraison project. +# SPDX-License-Identifier: Apache-2.0 +.DEFAULT_GOAL := test + +GOPKG := github.com/veraison/services/scheme/sevsnp +SRCS := $(wildcard *.go) + +SUBDIR += plugin + +include ../../mk/common.mk +include ../../mk/lint.mk +include ../../mk/pkg.mk +include ../../mk/subdir.mk +include ../../mk/test.mk diff --git a/scheme/sevsnp/README.md b/scheme/sevsnp/README.md new file mode 100644 index 00000000..63d3967e --- /dev/null +++ b/scheme/sevsnp/README.md @@ -0,0 +1,68 @@ +# SEV-SNP scheme + +This scheme supports the provisioning of reference values and appraisal of evidence. It is suitable for anyone performing verification of simple SEV-SNP evidence. + +## Installation + +It doesn't need any specific install instructions, it gets deployed along with other schemes. +``` +make really-clean && make native-deploy +``` + +## Usage example + +Following is an example of how to interface with this scheme/plugin. The workflow involves using cocli to submit Reference Values and [ratsd](https://github.com/veraison/ratsd) to submit Evidence. + +Generating Reference Values and Evidence is beyond this project's scope. Please see [go-gen-ref](https://github.com/jraman567/go-gen-ref) for creating Reference Values for SEV-SNP; ratsd generates Evidence. + +### Provisioning Trust Anchor +``` +cocli comid create --template scheme/sevsnp/test/ta-prov.json +cocli corim create -m ta-prov.cbor -t corimMini.json -o ta.cbor +cocli corim submit --corim-file=ta.cbor --api-server="https://localhost:9443/endorsement-provisioning/v1/submit" --media-type="application/corim-unsigned+cbor; profile=\"https://amd.com/ark\"" +``` + +### Provisioning Reference Values +``` +cocli corim submit --corim-file=scheme/sevsnp/test/refval-prov.cbor --api-server="https://localhost:9443/endorsement-provisioning/v1/submit" --media-type="application/corim-unsigned+cbor; profile=\"https://amd.com/ark\"" +``` + +### Submitting Evidence +``` +git clone https://github.com/veraison/ratsd.git +cd ratsd; go build +# From the following command, note down the nonce (in the body) and +# session-id (location in the header), and save them as NONCE and +# SESSION_ID environment variables respectively +curl -sSk -X POST "https://:8443/challenge-response/v1/newSession?nonceSize=64" -H "accept: application/vnd.veraison.challenge-response-session+json" -i +EVIDENCE_TOKEN=$(curl -sS -X POST http://:8895/ratsd/chares -H "Content-Type: application/vnd.veraison.chares+json" -d "{\"nonce\":\"$NONCE\"}") +ATTESTATION_RESULT=$(curl -sSk -X POST -H "https://localhost:8443/$SESSION_ID \ + -H "accept: application/vnd.veraison.challenge-response-session+json" \ + -H 'Content-Type: application/eat+cwt; eat_profile="tag:github.com,2025:veraison/ratsd/cmw"' \ + -H "Host: localhost:8443" \ + --data-raw "$EVIDENCE_TOKEN") +echo $ATTESTATION_RESULT +``` + +## Result +The result is in JWT format. We can print and verify the result using the [ARC tool](https://github.com/veraison/ear/tree/main/arc) as follows. +``` +go install github.com/veraison/ear/arc@latest +arc print result.jwt +``` +The trustworthiness vector, as shown below, summarizes the result of verification. +``` + "SEVSNP": { + "ear.appraisal-policy-id": "policy:SEVSNP", + "ear.status": "affirming", + "ear.trustworthiness-vector": { + "configuration": 0, + "executables": 0, + "file-system": 0, + "hardware": 2, + "instance-identity": 0, + "runtime-opaque": 2, + "sourced-data": 0, + "storage-opaque": 0 + }, +``` \ No newline at end of file diff --git a/scheme/sevsnp/common.go b/scheme/sevsnp/common.go new file mode 100644 index 00000000..8e196eaf --- /dev/null +++ b/scheme/sevsnp/common.go @@ -0,0 +1,207 @@ +// Copyright 2025 Contributors to the Veraison project. +// SPDX-License-Identifier: Apache-2.0 + +package sevsnp + +import ( + "encoding/base64" + "encoding/json" + "encoding/pem" + "errors" + "fmt" + "reflect" + "strconv" + + "github.com/google/go-sev-guest/abi" + "github.com/google/go-sev-guest/kds" + "github.com/google/go-sev-guest/proto/sevsnp" + "github.com/veraison/cmw" + "github.com/veraison/corim/comid" + "github.com/veraison/corim/corim" + "github.com/veraison/ratsd/tokens" + "github.com/veraison/services/handler" + "github.com/veraison/services/proto" +) + +var ( + ErrCertificateReadFailure = errors.New("failed to read certificate") + ErrMissingCertChain = errors.New("evidence missing certificate chain") + ErrMissingCMW = errors.New("CMW not found in evidence token") +) + +// measurementByUintKey looks up comid.Measurement in a CoMID by its MKey. +// +// If no measurements are found, returns nil and no error. Otherwise, +// returns the error encountered. +func measurementByUintKey(refVal comid.ValueTriple, + key uint64) (*comid.Measurement, error) { + for _, m := range refVal.Measurements.Values { + if m.Key == nil || !m.Key.IsSet() || + m.Key.Type() != comid.UintType { + continue + } + + k, err := m.Key.GetKeyUint() + if err != nil { + return nil, err + } + + if k == key { + return &m, nil + } + } + + return nil, nil +} + +// comidFromJson accepts a CoRIM in JSON format and returns its first CoMID +// +// Returns error if there are more than a single CoMID, or passes on +// error from corim routine. +func comidFromJson(buf []byte) (*comid.Comid, error) { + extractedCorim, err := corim.UnmarshalUnsignedCorimFromJSON(buf) + if err != nil { + return nil, err + } + + if len(extractedCorim.Tags) > 1 { + return nil, errors.New("too many tags") + } + + extractedComid, err := corim.UnmarshalComidFromCBOR( + extractedCorim.Tags[0].Content, + extractedCorim.Profile, + ) + + if err != nil { + return nil, err + } + + return extractedComid, nil +} + +func parseCertificateChainFromEvidence(tsm *tokens.TSMReport) (*sevsnp.CertificateChain, error) { + var certTable abi.CertTable + + if len(tsm.AuxBlob) == 0 { + return nil, ErrMissingCertChain + } + + if err := certTable.Unmarshal(tsm.AuxBlob); err != nil { + return nil, err + } + + return certTable.Proto(), nil +} + +func readCert(cert []byte) ([]byte, error) { + if len(cert) == 0 { + return nil, errors.New("empty certificate") + } + + block, _ := pem.Decode(cert) + if block == nil || block.Type != "CERTIFICATE" { + return nil, ErrCertificateReadFailure + } + return block.Bytes, nil +} + +func parseAttestationToken(token *proto.AttestationToken) (*tokens.TSMReport, error) { + var ( + err error + tsm = new(tokens.TSMReport) + cmwCollection cmw.CMW + ) + + switch token.MediaType { + case EvidenceMediaTypeTSMCbor: + err = tsm.FromCBOR(token.Data) + if err != nil { + return nil, err + } + case EvidenceMediaTypeTSMJson: + err = tsm.FromJSON(token.Data) + if err != nil { + return nil, err + } + case EvidenceMediaTypeRATSd: + eat := make(map[string]interface{}) + + err = json.Unmarshal(token.Data, &eat) + if err != nil { + return nil, err + } + + cmwBase64, ok := eat["cmw"].(string) + if !ok { + return nil, handler.BadEvidence(ErrMissingCMW) + } + + cmwJson, err := base64.StdEncoding.DecodeString(cmwBase64) + if err != nil { + return nil, err + } + + err = cmwCollection.UnmarshalJSON(cmwJson) + if err != nil { + return nil, err + } + + cmwMonad, err := cmwCollection.GetCollectionItem("tsm-report") + if err != nil { + return nil, err + } + + cmwType, err := cmwMonad.GetMonadType() + if err != nil { + return nil, err + } + if cmwType != "application/vnd.veraison.configfs-tsm+json" { + return nil, fmt.Errorf("unexpected CMW type: %s", cmwType) + } + cmwValue, err := cmwMonad.GetMonadValue() + if err != nil { + return nil, err + } + + err = tsm.FromJSON(cmwValue) + if err != nil { + return nil, err + } + default: + return nil, fmt.Errorf("unexpected media type: %s", token.MediaType) + } + + return tsm, nil +} + +// transformSVNtoTCB extracts TCB from the supplied SVN. SEV-SNP's TCB_VERSION +// is a composite version; it's bitfield consisting of SVNs from various firmware components +func transformSVNtoTCB(svn comid.SVN) (*kds.TCBParts, error) { + var ( + tcbVersion uint64 + err error + tcbParts kds.TCBParts + ) + + // ToDo: following is a circuitous way to obtain the 64-bit TCB integer value + // from SVN. Consider updating the SVN type to return a 64-bit value + switch v := svn.Value.(type) { + case *comid.TaggedSVN: + tcbString := v.String() + tcbVersion, err = strconv.ParseUint(tcbString, 10, 64) + case *comid.TaggedMinSVN: + tcbString := v.String() + tcbVersion, err = strconv.ParseUint(tcbString, 10, 64) + default: + err = fmt.Errorf("unsupported SVN type: %v", reflect.TypeOf(svn.Value)) + } + + if err != nil { + return nil, err + } + + tcbParts = kds.DecomposeTCBVersion(kds.TCBVersion(tcbVersion)) + + return &tcbParts, nil +} diff --git a/scheme/sevsnp/endorsement_handler.go b/scheme/sevsnp/endorsement_handler.go new file mode 100644 index 00000000..0053d9d4 --- /dev/null +++ b/scheme/sevsnp/endorsement_handler.go @@ -0,0 +1,64 @@ +// Copyright 2025 Contributors to the Veraison project. +// SPDX-License-Identifier: Apache-2.0 + +package sevsnp + +import ( + "errors" + "mime" + + "github.com/veraison/services/handler" + "github.com/veraison/services/scheme/common" +) + +// EndorsementHandler implements the IEndorsementHandler interface for SEVSNP scheme +type EndorsementHandler struct{} + +// Init initializes the endorsement handler instance. no-op for SEVSNP +func (o EndorsementHandler) Init(params handler.EndorsementHandlerParams) error { + return nil // no-op +} + +// Close closes the endorsement handler instance. no-op for SEVSNP +func (o EndorsementHandler) Close() error { + return nil // no-op +} + +// GetName returns the name of the endorsement handler +func (o EndorsementHandler) GetName() string { + return SchemeName +} + +// GetAttestationScheme returns the scheme name +func (o EndorsementHandler) GetAttestationScheme() string { + return SchemeName +} + +// GetSupportedMediaTypes returns the media types supported for SEVSNP endorsements +func (o EndorsementHandler) GetSupportedMediaTypes() []string { + return EndorsementMediaTypes +} + +// Decode decodes the supplied endorsement as an unsigned CoRIM +func (o EndorsementHandler) Decode(data []byte, mediaType string, caCertPool []byte) (*handler.EndorsementHandlerResponse, error) { + extractor := &Extractor{} + + if mediaType != "" { + mt, _, err := mime.ParseMediaType(mediaType) + if err != nil { + return nil, err + } + + // Use signed decoder for signed CoRIM + if mt == "application/rim+cose" { + return common.SignedCorimDecoder(data, extractor, caCertPool) + } + } + + // Default to unsigned CoRIM decoder + return common.UnsignedCorimDecoder(data, extractor) +} + +func (o EndorsementHandler) CoservRepackage(coservQuery string, resultSet []string) ([]byte, error) { + return nil, errors.New("SEV-SNP CoservRepackage not implemented") +} diff --git a/scheme/sevsnp/endorsement_handler_test.go b/scheme/sevsnp/endorsement_handler_test.go new file mode 100644 index 00000000..fa1ce7c3 --- /dev/null +++ b/scheme/sevsnp/endorsement_handler_test.go @@ -0,0 +1,46 @@ +// Copyright 2025 Contributors to the Veraison project. +// SPDX-License-Identifier: Apache-2.0 +package sevsnp + +import ( + "testing" + + "github.com/stretchr/testify/assert" +) + +func TestDecoder_GetName(t *testing.T) { + d := &EndorsementHandler{} + + expected := SchemeName + + actual := d.GetName() + + assert.Equal(t, expected, actual) +} + +func TestDecoder_GetAttestationScheme(t *testing.T) { + d := &EndorsementHandler{} + + expected := SchemeName + + actual := d.GetAttestationScheme() + + assert.Equal(t, expected, actual) +} + +func TestDecoder_GetSupportedMediaTypes(t *testing.T) { + d := &EndorsementHandler{} + + expected := EndorsementMediaTypes + + actual := d.GetSupportedMediaTypes() + + assert.Equal(t, expected, actual) +} + +func TestDecoder_Decode_OK(t *testing.T) { + d := &EndorsementHandler{} + + _, err := d.Decode(unsignedCorimSevSnp, "", nil) + assert.NoError(t, err) +} diff --git a/scheme/sevsnp/evidence_handler.go b/scheme/sevsnp/evidence_handler.go new file mode 100644 index 00000000..9b37a71e --- /dev/null +++ b/scheme/sevsnp/evidence_handler.go @@ -0,0 +1,564 @@ +// Copyright 2025 Contributors to the Veraison project. +// SPDX-License-Identifier: Apache-2.0 + +package sevsnp + +import ( + "bytes" + "encoding/json" + "errors" + "fmt" + "time" + + "github.com/google/go-sev-guest/abi" + "github.com/google/go-sev-guest/proto/sevsnp" + "github.com/google/go-sev-guest/verify" + "github.com/google/go-sev-guest/verify/trust" + sevsnpParser "github.com/jraman567/go-gen-ref/cmd/sevsnp" + "github.com/veraison/corim/comid" + "github.com/veraison/corim/corim" + "github.com/veraison/ear" + "github.com/veraison/ratsd/tokens" + "github.com/veraison/services/handler" + "github.com/veraison/services/log" + "github.com/veraison/services/proto" +) + +var ( + ErrNoARK = errors.New("missing ARK certificate in evidence") + ErrNoASK = errors.New("missing ASK certificate in evidence") + ErrNoVEK = errors.New("evidence must supply VLEK or VCEK") + ErrNoVCEK = errors.New("VCEK is missing") + ErrNoVLEK = errors.New("VLEK is missing") + ErrTAMismatch = errors.New("evidence Trust Anchor (ARK) doesn't match the provisioned one") + ErrNoProvisionedTA = errors.New("missing provisioned Trust Anchor") + ErrNoProvisionedRV = errors.New("reference value unavailable for attester") + ErrBadSigningKey = errors.New("bad signing key in attestation report") + ErrMismatchedReportedTCB = errors.New("reported TCB in evidence doesn't match reference") + ErrReferenceMissingSVN = errors.New("reference doesn't have SVN") + ErrEvidenceMissingSVN = errors.New("evidence doesn't have SVN") +) + +const ( + ReportSigningKeyVcek = 0 + ReportSigningKeyVlek = 1 +) + +// EvidenceHandler implements the IEvidenceHandler interface for SEVSNP +type EvidenceHandler struct { +} + +// GetName returns the name of this evidence handler instance +func (o EvidenceHandler) GetName() string { + return "sevsnp-evidence-handler" +} + +// GetAttestationScheme returns the attestation scheme +func (o EvidenceHandler) GetAttestationScheme() string { + return SchemeName +} + +// GetSupportedMediaTypes returns the supported media types for the SEVSNP scheme +func (o EvidenceHandler) GetSupportedMediaTypes() []string { + return EvidenceMediaTypes +} + +func transformEvidenceToCorim(token *proto.AttestationToken) (*corim.UnsignedCorim, error) { + tsm, err := parseAttestationToken(token) + if err != nil { + return nil, err + } + + reportProto, err := abi.ReportToProto(tsm.OutBlob) + if err != nil { + return nil, err + } + + evComid, err := sevsnpParser.ReportToComid(reportProto, 0) + if err != nil { + return nil, err + } + + err = evComid.Valid() + if err != nil { + return nil, err + } + + evCorim := corim.UnsignedCorim{} + evCorim.SetProfile(EndorsementMediaTypeRV) + evCorim.AddComid(evComid) + + return &evCorim, nil +} + +// ExtractClaims converts evidence in tsm-report format to our +// "internal representation", which is in CoRIM format. +func (o EvidenceHandler) ExtractClaims( + token *proto.AttestationToken, + _ []string, +) (map[string]interface{}, error) { + var claimsSet map[string]interface{} + + evCorim, err := transformEvidenceToCorim(token) + if err != nil { + return nil, err + } + + evJson, err := evCorim.ToJSON() + if err != nil { + return nil, err + } + + err = json.Unmarshal(evJson, &claimsSet) + if err != nil { + return nil, err + } + + return claimsSet, nil +} + +func extractProvisionedTA(trustAnchors []string) (*comid.CryptoKey, error) { + var ( + taEndorsement *handler.Endorsement + avk comid.KeyTriple + ) + + for i, t := range trustAnchors { + var endorsement handler.Endorsement + + if err := json.Unmarshal([]byte(t), &endorsement); err != nil { + return nil, fmt.Errorf("could not decode endorsement at index %d: %w", i, err) + } + + if endorsement.Type == handler.EndorsementType_VERIFICATION_KEY { + taEndorsement = &endorsement + break + } + } + + if taEndorsement == nil { + return nil, handler.BadEvidence(ErrNoProvisionedTA) + } + + err := json.Unmarshal(taEndorsement.Attributes, &avk) + if err != nil { + return nil, err + } + + // The StoreHandler takes care of ensuring that only one TA is + // supplied, we don't have to re-check it here. + provisionedArk := avk.VerifKeys[0] + + return provisionedArk, nil +} + +func validateCertificateChain(certChain *sevsnp.CertificateChain) error { + if len(certChain.GetArkCert()) == 0 { + return handler.BadEvidence(ErrNoARK) + } + + if len(certChain.GetAskCert()) == 0 { + return handler.BadEvidence(ErrNoASK) + } + + if len(certChain.GetVcekCert()) == 0 && len(certChain.GetVlekCert()) == 0 { + return handler.BadEvidence(ErrNoVEK) + } + + return nil +} + +func validateTA(certChain *sevsnp.CertificateChain, provisionedArk *comid.CryptoKey) error { + if !bytes.Equal(certChain.GetArkCert(), []byte(provisionedArk.String())) { + return handler.BadEvidence(ErrTAMismatch) + } + + return nil +} + +func validateReportIntegrity(tsm *tokens.TSMReport, certChain *sevsnp.CertificateChain) error { + var ( + ark, ask, vcek, vlek []byte + attestation sevsnp.Attestation + ) + + // options: options to use when verifying SEV-SNP evidence + // not feasible to enable certificate fetching and + // checking revocations as AMD KDS rate-limits requests + options := verify.Options{ + Getter: trust.DefaultHTTPSGetter(), + Now: time.Now(), + DisableCertFetching: true, + CheckRevocations: false, + } + + protoReport, err := abi.ReportToProto(tsm.OutBlob) + if err != nil { + return err + } + attestation.Report = protoReport + + if ark, err = readCert(certChain.GetArkCert()); err != nil { + return fmt.Errorf("can't read ARK to validate cert chain: %w", err) + } + + if ask, err = readCert(certChain.GetAskCert()); err != nil { + return fmt.Errorf("can't read ASK to validate cert chain: %w", err) + } + + signerInfo, err := abi.ParseSignerInfo(protoReport.GetSignerInfo()) + if err != nil { + return err + } + + switch signerInfo.SigningKey { + case ReportSigningKeyVlek: + if len(certChain.GetVlekCert()) == 0 { + return ErrNoVLEK + } + if vlek, err = readCert(certChain.GetVlekCert()); err != nil { + return fmt.Errorf("can't read VLEK to validate cert chain: %w", err) + } + attestation.CertificateChain = &sevsnp.CertificateChain{VlekCert: vlek, AskCert: ask, ArkCert: ark} + case ReportSigningKeyVcek: + if len(certChain.GetVcekCert()) == 0 { + return ErrNoVCEK + } + if vcek, err = readCert(certChain.GetVcekCert()); err != nil { + return fmt.Errorf("can't read VCEK to validate cert chain: %w", err) + } + attestation.CertificateChain = &sevsnp.CertificateChain{VcekCert: vcek, AskCert: ask, ArkCert: ark} + default: + return ErrBadSigningKey + } + + err = verify.SnpAttestation(&attestation, &options) + if err != nil { + return handler.BadEvidence(err) + } + + return nil +} + +func validateSessionNonce(tsm *tokens.TSMReport, sessionNonce []byte) error { + reportProto, err := abi.ReportToProto(tsm.OutBlob) + if err != nil { + return err + } + + evNonce := reportProto.GetReportData() + + if !bytes.Equal(evNonce, sessionNonce) { + return handler.BadEvidence(fmt.Errorf("nonce in the evidence doesn't match the session nonce. evidence: 0x%x vs session: 0x%x", evNonce, sessionNonce)) + } + + return nil +} + +// ValidateEvidenceIntegrity confirms the integrity of evidence by doing the following: +// - verifies that the TA in the evidence matches the provisioned TA +// - confirms the integrity of the certificate chain +// - validates the integrity of evidence by checking its signature +func (o EvidenceHandler) ValidateEvidenceIntegrity( + token *proto.AttestationToken, + trustAnchors []string, + _ []string, +) error { + var ( + tsm *tokens.TSMReport + provisionedArk *comid.CryptoKey + certChain *sevsnp.CertificateChain + err error + ) + + if tsm, err = parseAttestationToken(token); err != nil { + return err + } + + if provisionedArk, err = extractProvisionedTA(trustAnchors); err != nil { + return err + } + + if certChain, err = parseCertificateChainFromEvidence(tsm); err != nil { + return err + } + + if err := validateCertificateChain(certChain); err != nil { + return err + } + + if err := validateTA(certChain, provisionedArk); err != nil { + return err + } + + if err := validateSessionNonce(tsm, token.Nonce); err != nil { + return err + } + + return validateReportIntegrity(tsm, certChain) +} + +// refvalToComidTriple converts extracted reference values to CoMID value triple +func refvalToComidTriple(endorsementsStrings []string) (*comid.ValueTriple, error) { + var ( + refValEndorsement *handler.Endorsement + rv comid.ValueTriple + ) + + for i, e := range endorsementsStrings { + var endorsement handler.Endorsement + + if err := json.Unmarshal([]byte(e), &endorsement); err != nil { + return nil, fmt.Errorf("could not decode endorsement at index %d: %w", i, err) + } + + if endorsement.Type == handler.EndorsementType_REFERENCE_VALUE { + refValEndorsement = &endorsement + break + } + } + + if refValEndorsement == nil { + return nil, handler.BadEvidence(ErrNoProvisionedRV) + } + + err := json.Unmarshal(refValEndorsement.Attributes, &rv) + if err != nil { + return nil, err + } + + return &rv, nil +} + +// evidenceToComidTriple converts claim set to CoMID value triple +func evidenceToComidTriple(ec *proto.EvidenceContext) (*comid.ValueTriple, error) { + evCorimJson, err := json.Marshal(ec.Evidence.AsMap()) + if err != nil { + return nil, err + } + + evComid, err := comidFromJson(evCorimJson) + if err != nil { + return nil, err + } + + return &evComid.Triples.ReferenceValues.Values[0], nil +} + +// compareMeasurements checks if two given comid.Measurement variables are equal. +func compareMeasurements(refM comid.Measurement, evM comid.Measurement) bool { + // RawValue comparison + if refM.Val.RawValue != nil { + if evM.Val.RawValue == nil { + return false + } + + refDigest, _ := refM.Val.RawValue.GetBytes() + return evM.Val.RawValue.CompareAgainstReference(refDigest, nil) + } + + // Digests comparison + if refM.Val.Digests != nil { + if evM.Val.Digests == nil { + return false + } + + return evM.Val.Digests.CompareAgainstReference(*refM.Val.Digests) + } + + // SVN comparison + if refM.Val.SVN != nil { + if evM.Val.SVN == nil { + log.Debugf("evidence doesn't have SVN") + return false + } + + if c, ok := evM.Val.SVN.Value.(*comid.TaggedSVN); ok { + if r, ok := refM.Val.SVN.Value.(*comid.TaggedSVN); ok { + return c.CompareAgainstRefSVN(*r) + } else if r, ok := refM.Val.SVN.Value.(*comid.TaggedMinSVN); ok { + return c.CompareAgainstRefMinSVN(*r) + } else { + log.Debugf("unknown refVal SVN type") + return false + } + } else if c, ok := evM.Val.SVN.Value.(*comid.TaggedMinSVN); ok { + if r, ok := refM.Val.SVN.Value.(*comid.TaggedMinSVN); ok { + return c.Equal(*r) + } + log.Debugf("can't compare TaggedMinSVN against TaggedSVN") + return false + } else { + log.Debugf("unknown evidence SVN type") + return false + } + } + + return true +} + +func compareTcb(refM comid.Measurement, evM comid.Measurement) bool { + if refM.Val.SVN == nil { + log.Errorf("%w", ErrReferenceMissingSVN) + return false + } + + if evM.Val.SVN == nil { + log.Errorf("%w", ErrEvidenceMissingSVN) + return false + } + + refTcbParts, err := transformSVNtoTCB(*refM.Val.SVN) + if err != nil { + log.Errorf("could not transform reference SVN to TCB parts: %v", err) + return false + } + + evTcbParts, err := transformSVNtoTCB(*evM.Val.SVN) + if err != nil { + log.Errorf("could not transform evidence SVN to TCB parts: %v", err) + } + + if evTcbParts.BlSpl < refTcbParts.BlSpl || + evTcbParts.SnpSpl < refTcbParts.SnpSpl || + evTcbParts.TeeSpl < refTcbParts.TeeSpl || + evTcbParts.UcodeSpl < refTcbParts.UcodeSpl { + return false + } + + return true +} + +// AppraiseEvidence confirms if the claims in the evidence match with the provisioned +// reference values. +// +// Appraisal can confirm if the evidence is genuinely generated by AMD +// hardware and if SEV-SNP enables memory encryption. As such, set the +// "Hardware" and "RuntimeOpaque" values in the trustworthiness vector; +// we can't infer other aspects of the vector from SEV-SNP evidence alone. +func (o EvidenceHandler) AppraiseEvidence( + ec *proto.EvidenceContext, + endorsementsStrings []string, +) (*ear.AttestationResult, error) { + var ( + err error + evidenceMap map[string]interface{} + ) + + refVal, err := refvalToComidTriple(endorsementsStrings) + if err != nil { + return nil, err + } + + evidence, err := evidenceToComidTriple(ec) + if err != nil { + return nil, err + } + + result := handler.CreateAttestationResult(SchemeName) + + appraisal := result.Submods[SchemeName] + + // Init TrustVector to default values + appraisal.TrustVector.InstanceIdentity = ear.NoClaim + appraisal.TrustVector.Executables = ear.NoClaim + appraisal.TrustVector.Configuration = ear.NoClaim + appraisal.TrustVector.FileSystem = ear.NoClaim + appraisal.TrustVector.StorageOpaque = ear.NoClaim + appraisal.TrustVector.SourcedData = ear.NoClaim + appraisal.TrustVector.Hardware = ear.UnsafeHardwareClaim + appraisal.TrustVector.RuntimeOpaque = ear.VisibleMemoryRuntimeClaim + +claimsLoop: + for _, m := range refVal.Measurements.Values { + var ( + k uint64 + em *comid.Measurement + ) + + k, err = m.Key.GetKeyUint() + if err != nil { + break + } + + // We can skip validating certain claims for the following reasons: + // - POLICY ToDo: Do we need to test individual policy features? + // - CURRENT_TCB is informational only. It's best handled by policy + // - PLATFORM_INFO ToDO: Do we need to test individual platform features? + // - REPORT_DATA is a nonce supplied by user for freshness. It's used + // for freshness verification, and verified as part of + // evidence integrity check (session nonce check). + // - REPORT_ID is ephemeral, so we can't use it for verification. + // - REPORT_ID_MA is also ephemeral, used for migration + // - CHIP_ID is unique to an specific attester, but reference values could be used more generally + // - Current Version (CURRENT_MAJOR/MINOR/BUILD) should already be part of REPORTED_TCB. + // ToDo: It is a good idea to test it anyway, but the Version type only tests for + // equality, and this would trigger spurious failures + // - COMMITTED_TCB is informational, used by the host to advance REPORTED_TCB + if k == mKeyPolicy || + k == mKeyCurrentTcb || + k == mKeyPlatformInfo || + k == mKeyReportData || + k == mKeyReportID || + k == mKeyReportIDMA || + k == mKeyChipID || + k == mKeyCommittedTcb || + k == mKeyCurrentVersion || + k == mKeyCommittedVersion { + continue + } + + em, err = measurementByUintKey(*evidence, k) + if err != nil { + break + } + + if em == nil { + err = fmt.Errorf("MKey %d not found in Evidence", k) + break + } + + switch k { + case mKeyReportedTcb: + if !compareTcb(m, *em) { + err = ErrMismatchedReportedTCB + break claimsLoop + } + case mKeyLaunchTcb: + reportedTcb, err := measurementByUintKey(*evidence, mKeyReportedTcb) + if err != nil { + break claimsLoop + } + if !compareTcb(*reportedTcb, *em) { + // ToDo: Is this a failure condition? + log.Errorf("TEE launched with older TCB version") + } + default: + if !compareMeasurements(m, *em) { + err = fmt.Errorf("MKey %d in reference value doesn't match with evidence", k) + break claimsLoop + } + } + } + + if err == nil { + appraisal.TrustVector.Hardware = ear.GenuineHardwareClaim + appraisal.TrustVector.RuntimeOpaque = ear.EncryptedMemoryRuntimeClaim + } + + appraisal.UpdateStatusFromTrustVector() + + evidenceJson, err := json.Marshal(evidence) + if err != nil { + return nil, err + } + + err = json.Unmarshal(evidenceJson, &evidenceMap) + if err != nil { + return nil, err + } + + appraisal.VeraisonAnnotatedEvidence = &evidenceMap + + return result, err +} diff --git a/scheme/sevsnp/evidence_handler_test.go b/scheme/sevsnp/evidence_handler_test.go new file mode 100644 index 00000000..5597c286 --- /dev/null +++ b/scheme/sevsnp/evidence_handler_test.go @@ -0,0 +1,177 @@ +// Copyright 2025 Contributors to the Veraison project. +// SPDX-License-Identifier: Apache-2.0 + +package sevsnp + +import ( + "encoding/json" + "github.com/stretchr/testify/assert" + "github.com/veraison/ear" + "os" + "testing" + + "github.com/stretchr/testify/require" + "github.com/veraison/services/proto" +) + +var testNonce = []byte{ + 77, 73, 68, 66, 78, 72, 50, 56, + 105, 105, 111, 105, 115, 106, 80, 121, + 120, 120, 120, 120, 120, 120, 120, 120, + 120, 120, 120, 120, 120, 120, 120, 120, + 77, 73, 68, 66, 78, 72, 50, 56, + 105, 105, 111, 105, 115, 106, 80, 121, + 120, 120, 120, 120, 120, 120, 120, 120, + 120, 120, 120, 120, 120, 120, 120, 120, +} + +var testBadNonce = []byte{ + 0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01, 0x00, + 0x0f, 0x0e, 0x0d, 0x0c, 0x0b, 0x0a, 0x09, 0x08, + 0x17, 0x16, 0x15, 0x14, 0x13, 0x12, 0x11, 0x10, + 0x1f, 0x1e, 0x1d, 0x1c, 0x1b, 0x1a, 0x19, 0x18, +} + +type sevSnpEvidence struct { + FileName string + MediaType string +} + +var testEvidenceList = []sevSnpEvidence{ + {"test/sevsnp-ratsd-token", EvidenceMediaTypeRATSd}, + {"test/sevsnp-tsm-report.json", EvidenceMediaTypeTSMJson}, + {"test/sevsnp-tsm-report.cbor", EvidenceMediaTypeTSMCbor}, +} + +func Test_ExtractClaims_ok(t *testing.T) { + for _, evidence := range testEvidenceList { + tokenBytes, err := os.ReadFile(evidence.FileName) + require.NoError(t, err) + + taEndValBytes, err := os.ReadFile("test/ta-endorsement.json") + require.NoError(t, err) + + handler := &EvidenceHandler{} + + token := proto.AttestationToken{ + TenantId: "0", + Data: tokenBytes, + MediaType: evidence.MediaType, + Nonce: testNonce, + } + ta := string(taEndValBytes) + _, err = handler.ExtractClaims(&token, []string{ta}) + + require.NoError(t, err) + } +} + +func Test_ValidateEvidenceIntegrity_ok(t *testing.T) { + for _, evidence := range testEvidenceList { + tokenBytes, err := os.ReadFile(evidence.FileName) + require.NoError(t, err) + + taEndValBytes, err := os.ReadFile("test/ta-endorsement.json") + require.NoError(t, err) + + handler := &EvidenceHandler{} + + token := proto.AttestationToken{ + TenantId: "0", + Data: tokenBytes, + MediaType: evidence.MediaType, + Nonce: testNonce, + } + + ta := string(taEndValBytes) + err = handler.ValidateEvidenceIntegrity(&token, []string{ta}, nil) + + assert.NoError(t, err) + } +} + +func Test_ValidateEvidenceIntegrity_BadTA(t *testing.T) { + tokenBytes, err := os.ReadFile("test/sevsnp-ratsd-token") + require.NoError(t, err) + + taEndValBytes, err := os.ReadFile("test/ta-endorsement-bad.json") + require.NoError(t, err) + + handler := &EvidenceHandler{} + + token := proto.AttestationToken{ + TenantId: "0", + Data: tokenBytes, + MediaType: EvidenceMediaTypeRATSd, + Nonce: testNonce, + } + + ta := string(taEndValBytes) + err = handler.ValidateEvidenceIntegrity(&token, []string{ta}, nil) + + assert.EqualError(t, err, "{\"detail\":[\"evidence Trust Anchor (ARK) doesn't match the provisioned one\"],\"detail-type\":\"error\",\"error\":\"bad evidence\"}") +} + +func Test_ValidateEvidenceIntegrity_BadNonce(t *testing.T) { + tokenBytes, err := os.ReadFile("test/sevsnp-ratsd-token") + require.NoError(t, err) + + taEndValBytes, err := os.ReadFile("test/ta-endorsement.json") + require.NoError(t, err) + + handler := &EvidenceHandler{} + + token := proto.AttestationToken{ + TenantId: "0", + Data: tokenBytes, + MediaType: EvidenceMediaTypeRATSd, + Nonce: testBadNonce, + } + + ta := string(taEndValBytes) + err = handler.ValidateEvidenceIntegrity(&token, []string{ta}, nil) + + assert.EqualError(t, err, "{\"detail\":[\"nonce in the evidence doesn't match the session nonce. evidence: 0x4d4944424e48323869696f69736a5079787878787878787878787878787878784d4944424e48323869696f69736a507978787878787878787878787878787878 vs session: 0x07060504030201000f0e0d0c0b0a090817161514131211101f1e1d1c1b1a1918\"],\"detail-type\":\"error\",\"error\":\"bad evidence\"}") +} + +func Test_AppraiseEvidence_ok(t *testing.T) { + for _, evidence := range testEvidenceList { + tokenBytes, err := os.ReadFile(evidence.FileName) + require.NoError(t, err) + + taEndValBytes, err := os.ReadFile("test/ta-endorsement.json") + require.NoError(t, err) + + handler := &EvidenceHandler{} + + token := proto.AttestationToken{ + TenantId: "0", + Data: tokenBytes, + MediaType: evidence.MediaType, + Nonce: testNonce, + } + ta := string(taEndValBytes) + claims, err := handler.ExtractClaims(&token, []string{ta}) + require.NoError(t, err) + + claimsJson, err := json.Marshal(claims) + require.NoError(t, err) + + var ec proto.EvidenceContext + ec.TenantId = "0" + ec.TrustAnchorIds = []string{"SEVSNP://ARK-Genoa"} + ec.ReferenceIds = []string{"SEVSNP://0/7699e6ac12ccdfd1dfac70e649ce1f046cb2afbb003438f4cdddfe2ccbe182fa5ffbe8dcdb930454324e10c52c788980"} + err = json.Unmarshal(claimsJson, &ec.Evidence) + require.NoError(t, err) + + endorsementsBytes, err := os.ReadFile("test/refval-endorsement.json") + require.NoError(t, err) + + result, err := handler.AppraiseEvidence(&ec, []string{string(endorsementsBytes)}) + require.NoError(t, err) + + attestation := result.Submods["SEVSNP"] + + assert.Equal(t, ear.TrustTierAffirming, *attestation.Status) + } +} diff --git a/scheme/sevsnp/extractor.go b/scheme/sevsnp/extractor.go new file mode 100644 index 00000000..240dfb72 --- /dev/null +++ b/scheme/sevsnp/extractor.go @@ -0,0 +1,66 @@ +// Copyright 2025 Contributors to the Veraison project. +// SPDX-License-Identifier: Apache-2.0 + +package sevsnp + +import ( + "encoding/json" + "fmt" + + "github.com/veraison/corim/comid" + "github.com/veraison/services/handler" +) + +type Extractor struct { + Profile string +} + +// RefValExtractor stores the CoMID values triples in the database as-is. +func (o Extractor) RefValExtractor(rvs comid.ValueTriples) ([]*handler.Endorsement, error) { + refVals := make([]*handler.Endorsement, 0, len(rvs.Values)) + + for _, rv := range rvs.Values { + rvAttrs, err := json.Marshal(&rv) + if err != nil { + return nil, err + } + + refVal := &handler.Endorsement{ + Scheme: SchemeName, + Type: handler.EndorsementType_REFERENCE_VALUE, + SubType: "measurements", + Attributes: rvAttrs, + } + + refVals = append(refVals, refVal) + } + + return refVals, nil +} + +// TaExtractor Processes the verification keys supplied in the Endorsement +// +// The trust anchor for SEV-SNP is AMD Root Key (ARK). Stores the key triple in the database as-is. +func (o Extractor) TaExtractor(avk comid.KeyTriple) (*handler.Endorsement, error) { + if len(avk.VerifKeys) > 1 { + return nil, fmt.Errorf("expecting at most one key, got %d keys", len(avk.VerifKeys)) + } + + taAttrs, err := json.Marshal(&avk) + if err != nil { + return nil, err + } + + ta := &handler.Endorsement{ + Scheme: SchemeName, + Type: handler.EndorsementType_VERIFICATION_KEY, + Attributes: taAttrs, + } + + return ta, nil +} + +// SetProfile sets the extractor profile +func (o *Extractor) SetProfile(profile string) { + o.Profile = profile +} diff --git a/scheme/sevsnp/plugin/Makefile b/scheme/sevsnp/plugin/Makefile new file mode 100644 index 00000000..c4428d4f --- /dev/null +++ b/scheme/sevsnp/plugin/Makefile @@ -0,0 +1,13 @@ +# Copyright 2025 Contributors to the Veraison project. +# SPDX-License-Identifier: Apache-2.0 + +ifndef COMBINED_PLUGINS + SUBDIR += endorsement-handler + SUBDIR += evidence-handler + SUBDIR += store-handler +else + SUBDIR += combined +endif + +include ../../../mk/common.mk +include ../../../mk/subdir.mk diff --git a/scheme/sevsnp/plugin/combined/Makefile b/scheme/sevsnp/plugin/combined/Makefile new file mode 100644 index 00000000..eb99b10a --- /dev/null +++ b/scheme/sevsnp/plugin/combined/Makefile @@ -0,0 +1,11 @@ +# Copyright 2025 Contributors to the Veraison project. +# SPDX-License-Identifier: Apache-2.0 + +PLUGIN := ../../../bin/sevsnp.plugin +GOPKG := github.com/veraison/services/scheme/sevsnp +SRCS := main.go + +include ../../../../mk/common.mk +include ../../../../mk/plugin.mk +include ../../../../mk/lint.mk +include ../../../../mk/test.mk diff --git a/scheme/sevsnp/plugin/combined/main.go b/scheme/sevsnp/plugin/combined/main.go new file mode 100644 index 00000000..17329190 --- /dev/null +++ b/scheme/sevsnp/plugin/combined/main.go @@ -0,0 +1,16 @@ +// Copyright 2025 Contributors to the Veraison project. +// SPDX-License-Identifier: Apache-2.0 +package main + +import ( + "github.com/veraison/services/handler" + "github.com/veraison/services/plugin" + scheme "github.com/veraison/services/scheme/sevsnp" +) + +func main() { + handler.RegisterEndorsementHandler(&scheme.EndorsementHandler{}) + handler.RegisterEvidenceHandler(&scheme.EvidenceHandler{}) + handler.RegisterStoreHandler(&scheme.StoreHandler{}) + plugin.Serve() +} diff --git a/scheme/sevsnp/plugin/endorsement-handler/Makefile b/scheme/sevsnp/plugin/endorsement-handler/Makefile new file mode 100644 index 00000000..fc2cf8da --- /dev/null +++ b/scheme/sevsnp/plugin/endorsement-handler/Makefile @@ -0,0 +1,11 @@ +# Copyright 2025 Contributors to the Veraison project. +# SPDX-License-Identifier: Apache-2.0 + +PLUGIN := ../../../bin/sevsnp-endorsement-handler.plugin +GOPKG := github.com/veraison/services/scheme/sevsnp +SRCS := main.go + +include ../../../../mk/common.mk +include ../../../../mk/plugin.mk +include ../../../../mk/lint.mk +include ../../../../mk/test.mk diff --git a/scheme/sevsnp/plugin/endorsement-handler/main.go b/scheme/sevsnp/plugin/endorsement-handler/main.go new file mode 100644 index 00000000..d8349094 --- /dev/null +++ b/scheme/sevsnp/plugin/endorsement-handler/main.go @@ -0,0 +1,14 @@ +// Copyright 2025 Contributors to the Veraison project. +// SPDX-License-Identifier: Apache-2.0 +package main + +import ( + "github.com/veraison/services/handler" + "github.com/veraison/services/plugin" + scheme "github.com/veraison/services/scheme/sevsnp" +) + +func main() { + handler.RegisterEndorsementHandler(&scheme.EndorsementHandler{}) + plugin.Serve() +} diff --git a/scheme/sevsnp/plugin/evidence-handler/Makefile b/scheme/sevsnp/plugin/evidence-handler/Makefile new file mode 100644 index 00000000..67e4a5ff --- /dev/null +++ b/scheme/sevsnp/plugin/evidence-handler/Makefile @@ -0,0 +1,11 @@ +# Copyright 2025 Contributors to the Veraison project. +# SPDX-License-Identifier: Apache-2.0 + +PLUGIN := ../../../bin/sevsnp-evidence-handler.plugin +GOPKG := github.com/veraison/services/scheme/sevsnp +SRCS := main.go + +include ../../../../mk/common.mk +include ../../../../mk/plugin.mk +include ../../../../mk/lint.mk +include ../../../../mk/test.mk diff --git a/scheme/sevsnp/plugin/evidence-handler/main.go b/scheme/sevsnp/plugin/evidence-handler/main.go new file mode 100644 index 00000000..9ed8f5c4 --- /dev/null +++ b/scheme/sevsnp/plugin/evidence-handler/main.go @@ -0,0 +1,14 @@ +// Copyright 2025 Contributors to the Veraison project. +// SPDX-License-Identifier: Apache-2.0 +package main + +import ( + "github.com/veraison/services/handler" + "github.com/veraison/services/plugin" + scheme "github.com/veraison/services/scheme/sevsnp" +) + +func main() { + handler.RegisterEvidenceHandler(&scheme.EvidenceHandler{}) + plugin.Serve() +} diff --git a/scheme/sevsnp/plugin/store-handler/Makefile b/scheme/sevsnp/plugin/store-handler/Makefile new file mode 100644 index 00000000..c309f787 --- /dev/null +++ b/scheme/sevsnp/plugin/store-handler/Makefile @@ -0,0 +1,11 @@ +# Copyright 2025 Contributors to the Veraison project. +# SPDX-License-Identifier: Apache-2.0 + +PLUGIN := ../../../bin/sevsnp-store-handler.plugin +GOPKG := github.com/veraison/services/scheme/sevsnp +SRCS := main.go + +include ../../../../mk/common.mk +include ../../../../mk/plugin.mk +include ../../../../mk/lint.mk +include ../../../../mk/test.mk diff --git a/scheme/sevsnp/plugin/store-handler/main.go b/scheme/sevsnp/plugin/store-handler/main.go new file mode 100644 index 00000000..63d58c94 --- /dev/null +++ b/scheme/sevsnp/plugin/store-handler/main.go @@ -0,0 +1,14 @@ +// Copyright 2025 Contributors to the Veraison project. +// SPDX-License-Identifier: Apache-2.0 +package main + +import ( + "github.com/veraison/services/handler" + "github.com/veraison/services/plugin" + scheme "github.com/veraison/services/scheme/sevsnp" +) + +func main() { + handler.RegisterStoreHandler(&scheme.StoreHandler{}) + plugin.Serve() +} diff --git a/scheme/sevsnp/scheme.go b/scheme/sevsnp/scheme.go new file mode 100644 index 00000000..6f2823de --- /dev/null +++ b/scheme/sevsnp/scheme.go @@ -0,0 +1,42 @@ +// Copyright 2025 Contributors to the Veraison project. +// SPDX-License-Identifier: Apache-2.0 +package sevsnp + +const ( + SchemeName = "SEVSNP" + EndorsementMediaTypeRV = `application/corim-unsigned+cbor; profile="tag:amd.com,2024:snp-corim-profile"` + // ToDo: check media type for AMD ARK + EndorsementMediaTypeTA = `application/corim-unsigned+cbor; profile="https://amd.com/ark"` + EvidenceMediaTypeTSMCbor = "application/vnd.veraison.tsm-report+cbor" + EvidenceMediaTypeTSMJson = "application/vnd.veraison.configfs-tsm+json" + EvidenceMediaTypeRATSd = `application/eat+cwt; eat_profile="tag:github.com,2025:veraison/ratsd/cmw"` +) + +var ( + EndorsementMediaTypes = []string{ + EndorsementMediaTypeRV, + EndorsementMediaTypeTA, + } + + EvidenceMediaTypes = []string{ + EvidenceMediaTypeTSMCbor, + EvidenceMediaTypeTSMJson, + EvidenceMediaTypeRATSd, + } +) + +const ( + mKeyPolicy = 2 + mKeyCurrentTcb = 6 + mKeyPlatformInfo = 7 + mKeyReportData = 640 + mKeyMeasurement = 641 + mKeyReportID = 645 + mKeyReportIDMA = 646 + mKeyReportedTcb = 647 + mKeyChipID = 3328 + mKeyCommittedTcb = 3329 + mKeyCurrentVersion = 3330 + mKeyCommittedVersion = 3936 + mKeyLaunchTcb = 3968 +) diff --git a/scheme/sevsnp/store_handler.go b/scheme/sevsnp/store_handler.go new file mode 100644 index 00000000..e30c0960 --- /dev/null +++ b/scheme/sevsnp/store_handler.go @@ -0,0 +1,199 @@ +// Copyright 2025 Contributors to the Veraison project. +// SPDX-License-Identifier: Apache-2.0 + +package sevsnp + +import ( + "crypto/x509" + "encoding/hex" + "encoding/json" + "encoding/pem" + "errors" + "fmt" + "net/url" + + "github.com/google/go-sev-guest/proto/sevsnp" + "github.com/veraison/corim/comid" + "github.com/veraison/ratsd/tokens" + "github.com/veraison/services/handler" + "github.com/veraison/services/proto" +) + +var ( + ErrMissingMeasurement = errors.New("measurement not found") + ErrARKDecodeFailure = errors.New("failed to decode ARK") + ErrUnsupportedMultipleEvidence = errors.New("unable to process multiple evidence in a single request") +) + +// StoreHandler implements the IStoreHandler interface handler for SEVSNP scheme +type StoreHandler struct{} + +// GetName returns the name of this StoreHandler instance +func (s StoreHandler) GetName() string { + return fmt.Sprintf("%s-store-handler", SchemeName) +} + +// GetAttestationScheme returns the attestation scheme +func (s StoreHandler) GetAttestationScheme() string { + return SchemeName +} + +// GetSupportedMediaTypes returns the supported media types; no-op for SEVSNP +func (s StoreHandler) GetSupportedMediaTypes() []string { + return nil +} + +// getRefValKey helper to compute RefVal key from CoMID value triple +func getRefValKey(rv comid.ValueTriple, tenantID string) (string, error) { + m, err := measurementByUintKey(rv, mKeyMeasurement) + if err != nil { + return "", err + } + + if m == nil { + return "", ErrMissingMeasurement + } + + d := m.Val.Digests + + u := url.URL{ + Scheme: SchemeName, + Host: tenantID, + Path: hex.EncodeToString((*d)[0].HashValue), + } + + return u.String(), nil +} + +// SynthKeysFromRefValue constructs SEV-SNP reference value of the form +// "SEVSNP:///". The measurement +// is unique to an attester instance and, as such, is +// the best candidate to use as the key. +func (s StoreHandler) SynthKeysFromRefValue( + tenantID string, + refValue *handler.Endorsement, +) ([]string, error) { + var rv comid.ValueTriple + + err := json.Unmarshal(refValue.Attributes, &rv) + if err != nil { + return nil, err + } + + refValKey, err := getRefValKey(rv, tenantID) + if err != nil { + return nil, err + } + + return []string{refValKey}, nil +} + +// SynthKeysFromTrustAnchor constructs the SEV-SNP Trust Anchor key. The +// key format is "SEVSNP://". For example, "SEV-SNP://ARK-Milan" +// +// AMD's Root Key (ARK) is the only Trust Anchor for SEV-SNP. +// +// The attester supplies all the keys in the certificate chain +// for verification. During verification, the scheme must ensure that +// the ARK in the evidence matches the provisioned Trust Anchor. +func (s StoreHandler) SynthKeysFromTrustAnchor(_ string, ta *handler.Endorsement) ([]string, error) { + var avk comid.KeyTriple + + err := json.Unmarshal(ta.Attributes, &avk) + if err != nil { + return nil, err + } + + ark := avk.VerifKeys[0] + + keyBlock, _ := pem.Decode([]byte(ark.String())) + if keyBlock == nil || keyBlock.Type != "CERTIFICATE" { + return nil, ErrARKDecodeFailure + } + + cert, err := x509.ParseCertificate(keyBlock.Bytes) + if err != nil { + return nil, err + } + + u := url.URL{ + Scheme: SchemeName, + Path: cert.Issuer.CommonName, + } + + return []string{u.String()}, nil +} + +// GetTrustAnchorIDs gets the TA ID from evidence +// +// "auxblob" in the TSM report contains a certificate +// table. Extract ARK from it and construct the TA key. +func (s StoreHandler) GetTrustAnchorIDs(token *proto.AttestationToken) ([]string, error) { + var ( + tsm *tokens.TSMReport + certChain *sevsnp.CertificateChain + ark []byte + cert *x509.Certificate + err error + ) + + if tsm, err = parseAttestationToken(token); err != nil { + return nil, err + } + + if certChain, err = parseCertificateChainFromEvidence(tsm); err != nil { + return nil, err + } + + if ark, err = readCert(certChain.GetArkCert()); err != nil { + return nil, fmt.Errorf("can't read ARK to compose TA ID: %w", err) + } + + if cert, err = x509.ParseCertificate(ark); err != nil { + return nil, err + } + + u := url.URL{ + Scheme: SchemeName, + Path: cert.Issuer.CommonName, + } + + return []string{u.String()}, nil +} + +// GetRefValueIDs gets the refval key from the claims set. Looks up +// "measurement" using its MKey (641) and construct the refval key. +// +// Reference value key for SEV-SNP is of the form +// "SEVSNP:///", as explained +// in SynthKeysFromRefValue. +func (s StoreHandler) GetRefValueIDs( + tenantID string, + _ []string, + claims map[string]interface{}, +) ([]string, error) { + claimsJson, err := json.Marshal(claims) + if err != nil { + return nil, err + } + + extractedComid, err := comidFromJson(claimsJson) + if err != nil { + return nil, err + } + + if len(extractedComid.Triples.ReferenceValues.Values) > 1 { + return nil, ErrUnsupportedMultipleEvidence + } + + refValKey, err := getRefValKey(extractedComid.Triples.ReferenceValues.Values[0], tenantID) + if err != nil { + return nil, err + } + + return []string{refValKey}, nil +} + +func (s StoreHandler) SynthCoservQueryKeys(tenantID string, query string) ([]string, error) { + return []string{"TODO"}, nil +} diff --git a/scheme/sevsnp/store_handler_test.go b/scheme/sevsnp/store_handler_test.go new file mode 100644 index 00000000..44faa199 --- /dev/null +++ b/scheme/sevsnp/store_handler_test.go @@ -0,0 +1,97 @@ +// Copyright 2025 Contributors to the Veraison project. +// SPDX-License-Identifier: Apache-2.0 +package sevsnp + +import ( + "encoding/json" + "github.com/veraison/services/proto" + "os" + "testing" + + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + "github.com/veraison/services/handler" +) + +func Test_SynthKeysFromRefValue_ok(t *testing.T) { + var e handler.Endorsement + + endorsementsBytes, err := os.ReadFile("test/refval-endorsement.json") + require.NoError(t, err) + + err = json.Unmarshal(endorsementsBytes, &e) + require.NoError(t, err) + expectedKey := "SEVSNP://0/7699e6ac12ccdfd1dfac70e649ce1f046cb2afbb003438f4cdddfe2ccbe182fa5ffbe8dcdb930454324e10c52c788980" + + scheme := &StoreHandler{} + keys, err := scheme.SynthKeysFromRefValue("0", &e) + require.NoError(t, err) + assert.Equal(t, expectedKey, keys[0]) + +} + +func Test_SynthKeysFromTrustAnchor_ok(t *testing.T) { + var e handler.Endorsement + + endorsementsBytes, err := os.ReadFile("test/ta-endorsement.json") + require.NoError(t, err) + + err = json.Unmarshal(endorsementsBytes, &e) + require.NoError(t, err) + + expectedKey := "SEVSNP://ARK-Genoa" + + scheme := &StoreHandler{} + keys, err := scheme.SynthKeysFromTrustAnchor("0", &e) + require.NoError(t, err) + assert.Equal(t, expectedKey, keys[0]) + +} + +func Test_GetTrustAnchorIDs_ok(t *testing.T) { + tokenBytes, err := os.ReadFile("test/sevsnp-ratsd-token") + require.NoError(t, err) + + token := proto.AttestationToken{ + TenantId: "0", + Data: tokenBytes, + MediaType: EvidenceMediaTypeRATSd, + Nonce: testNonce, + } + + expectedTaID := "SEVSNP://ARK-Genoa" + + handler := &StoreHandler{} + + taIDs, err := handler.GetTrustAnchorIDs(&token) + require.NoError(t, err) + assert.Equal(t, 1, len(taIDs)) + assert.Equal(t, expectedTaID, taIDs[0]) +} + +func Test_GetRefValueIDs_ok(t *testing.T) { + tokenBytes, err := os.ReadFile("test/sevsnp-ratsd-token") + require.NoError(t, err) + + taEndValBytes, err := os.ReadFile("test/ta-endorsement.json") + require.NoError(t, err) + + handler := &EvidenceHandler{} + + token := proto.AttestationToken{ + TenantId: "0", + Data: tokenBytes, + MediaType: EvidenceMediaTypeRATSd, + Nonce: testNonce, + } + ta := string(taEndValBytes) + claims, err := handler.ExtractClaims(&token, []string{ta}) + require.NoError(t, err) + + expectedRefvalIDs := []string{"SEVSNP://0/7699e6ac12ccdfd1dfac70e649ce1f046cb2afbb003438f4cdddfe2ccbe182fa5ffbe8dcdb930454324e10c52c788980"} + + scheme := &StoreHandler{} + refvalIDs, err := scheme.GetRefValueIDs("0", nil, claims) + require.NoError(t, err) + assert.Equal(t, expectedRefvalIDs, refvalIDs) +} diff --git a/scheme/sevsnp/test/corim/unsignedCorimSevSnp.cbor b/scheme/sevsnp/test/corim/unsignedCorimSevSnp.cbor new file mode 100644 index 00000000..11aba391 Binary files /dev/null and b/scheme/sevsnp/test/corim/unsignedCorimSevSnp.cbor differ diff --git a/scheme/sevsnp/test/refval-endorsement.json b/scheme/sevsnp/test/refval-endorsement.json new file mode 100644 index 00000000..aba54a1e --- /dev/null +++ b/scheme/sevsnp/test/refval-endorsement.json @@ -0,0 +1,272 @@ +{ + "scheme": "SEVSNP", + "type": "reference value", + "subType": "measurements", + "attributes": { + "environment": { + "class": { + "id": { + "type": "oid", + "value": "1.3.6.1.4.1.3704.3.1" + } + }, + "instance": { + "type": "bytes", + "value": "wqZSi3Nk4H6fXGU6s6oNvXOE+agN/eVMxkPdu4nYk2Ql/4oyVoym7XcQINw5wzzP+ztDysDFAaAJPK1gEt/T7Q==" + } + }, + "measurements": [ + { + "key": { + "type": "uint", + "value": 0 + }, + "value": { + "version": { + "value": "3", + "scheme": "decimal" + } + } + }, + { + "key": { + "type": "uint", + "value": 1 + }, + "value": { + "svn": { + "type": "min-value", + "value": 0 + } + } + }, + { + "key": { + "type": "uint", + "value": 2 + }, + "value": { + "raw-value": { + "type": "bytes", + "value": "AAAAAAADAAA=" + } + } + }, + { + "key": { + "type": "uint", + "value": 3 + }, + "value": { + "raw-value": { + "type": "bytes", + "value": "AAAAAAAAAAAAAAAAAAAAAA==" + } + } + }, + { + "key": { + "type": "uint", + "value": 4 + }, + "value": { + "raw-value": { + "type": "bytes", + "value": "AAAAAAAAAAAAAAAAAAAAAA==" + } + } + }, + { + "key": { + "type": "uint", + "value": 5 + }, + "value": { + "raw-value": { + "type": "bytes", + "value": "AAAAAA==" + } + } + }, + { + "key": { + "type": "uint", + "value": 6 + }, + "value": { + "svn": { + "type": "exact-value", + "value": 15787368493747273732 + } + } + }, + { + "key": { + "type": "uint", + "value": 7 + }, + "value": { + "raw-value": { + "type": "bytes", + "value": "AAAAAAAAACU=" + } + } + }, + { + "key": { + "type": "uint", + "value": 640 + }, + "value": { + "raw-value": { + "type": "bytes", + "value": "dRhKhRXGvbFREoFUv7JrFG1zSIoFxY1sEX3wXcjefrNYF2Dx2AOZ7zX9Y+KQIGGOAkeWHY42R3qPWjmwKe6gdQ==" + } + } + }, + { + "key": { + "type": "uint", + "value": 641 + }, + "value": { + "digests": [ + "sha-384;dpnmrBLM39HfrHDmSc4fBGyyr7sANDj0zd3+LMvhgvpf++jc25MEVDJOEMUseImA" + ] + } + }, + { + "key": { + "type": "uint", + "value": 645 + }, + "value": { + "raw-value": { + "type": "bytes", + "value": "/+c6C6N5+yXqu2wvt1AbmaZurPkr962gp1ajsWQrXOQ=" + } + } + }, + { + "key": { + "type": "uint", + "value": 646 + }, + "value": { + "raw-value": { + "type": "bytes", + "value": "//////////////////////////////////////////8=" + } + } + }, + { + "key": { + "type": "uint", + "value": 647 + }, + "value": { + "svn": { + "type": "exact-value", + "value": 6059311823650291722 + } + } + }, + { + "key": { + "type": "uint", + "value": 648 + }, + "value": { + "raw-value": { + "type": "bytes", + "value": "GQ==" + } + } + }, + { + "key": { + "type": "uint", + "value": 649 + }, + "value": { + "raw-value": { + "type": "bytes", + "value": "EQ==" + } + } + }, + { + "key": { + "type": "uint", + "value": 650 + }, + "value": { + "raw-value": { + "type": "bytes", + "value": "AQ==" + } + } + }, + { + "key": { + "type": "uint", + "value": 3328 + }, + "value": { + "raw-value": { + "type": "bytes", + "value": "wqZSi3Nk4H6fXGU6s6oNvXOE+agN/eVMxkPdu4nYk2Ql/4oyVoym7XcQINw5wzzP+ztDysDFAaAJPK1gEt/T7Q==" + } + } + }, + { + "key": { + "type": "uint", + "value": 3329 + }, + "value": { + "svn": { + "type": "exact-value", + "value": 15787368493747273732 + } + } + }, + { + "key": { + "type": "uint", + "value": 3330 + }, + "value": { + "version": { + "value": "1.55.29", + "scheme": "semver" + } + } + }, + { + "key": { + "type": "uint", + "value": 3936 + }, + "value": { + "version": { + "value": "1.55.29", + "scheme": "semver" + } + } + }, + { + "key": { + "type": "uint", + "value": 3968 + }, + "value": { + "svn": { + "type": "exact-value", + "value": 15787368493747273732 + } + } + } + ] + } +} diff --git a/scheme/sevsnp/test/refval-prov.cbor b/scheme/sevsnp/test/refval-prov.cbor new file mode 100644 index 00000000..4f5ea9c0 Binary files /dev/null and b/scheme/sevsnp/test/refval-prov.cbor differ diff --git a/scheme/sevsnp/test/sevsnp-ratsd-token b/scheme/sevsnp/test/sevsnp-ratsd-token new file mode 100644 index 00000000..443cb964 --- /dev/null +++ b/scheme/sevsnp/test/sevsnp-ratsd-token @@ -0,0 +1 @@ +{"cmw":"eyJfX2Ntd2NfdCI6InRhZzpnaXRodWIuY29tLDIwMjU6dmVyYWlzb24vcmF0c2QvY213IiwidHNtLXJlcG9ydCI6WyJhcHBsaWNhdGlvbi92bmQudmVyYWlzb24uY29uZmlnZnMtdHNtK2pzb24iLCJleUpoZFhoaWJHOWlJam9pZDB4UlIzQkxaMFJUVmt0WVVYb3RNa0ZWZWxGeWJVRkJRVUZFYkVOQlFVRlRjbVY2WldKMWMxUXRVMmRNZDFkMU9IbG1TR2RyVlVwQlFVRldRMUZCUVZrNWNERnFaVnByVWxkVGRIaG1VelZQTFdsemVsWnZVMEZCUWxoQ2QwRkJRVUZCUVVGQlFVRkJRVUZCUVVGQlFVRkJRVUZCUVVGQlFVRkJRVUZCUVVGTVV6QjBURk14UTFKVlpFcFVhVUpFVWxaS1ZWTlZXa3BSTUVaVlVsTXdkRXhUTUhSRGF6RktVMVZrV21WclRrUlJhMHBNV2pCR00xTlZTa0phTUd4RlVWZGtRbEZWTVVaWFZXUkVWVE5HU0ZVd2JHbE5NRkpTVWxWS1JHRnJSVEZpTUVVMFpEQlNVbGRWY0ZwVFZuQktVVlprVmxKRlNrSlRWVTFMVVd4R1JHRkZhRVZSVjBaRFdqSjBlR0ZIZEhCU2Vtd3pUVVZLUWxWWFpETlNSa1phVTJ4c1NsZHJiRUpXTVZaRlVXdEdTbEV3U2xKUk1teENaREJzUTFSVmRFNVNSVVp1VWxWS1RsTklUalJTYTFKQ1ZYZHdRMW93TlZkUmEwWjZWRlZOZDFadVZtRk5iWGd4VjJ4a1YyVlhSbGhPVnpWT1ZWaE9NMUV4UmxwU1JscFNWVlZrUm1Rd2NGZFdXSEJHVmxVeFExTlZaRUpOVmxaR1VXNWtNMVJHVlhsU2JsWnJVakJXYmtOc1JYbGxSMmhxWWxWV05GRXpjRUpUYTBwdVZHeGFRMUZYWkU1UlYzUlBVV3N4VTA5SVpFbFZWbXhGVm14R1VsTXdVa05YYTBwaFUwWndiMWx0TVU5aVJuQkVVV3MxYUZZd05UVlpibXhEVWxad1dWZHVRVXRYVkVwWFpXc3hVMU5ZWkVaUlZteEZWbXhHVWxKRlVrSmlSVXBXWVROT01GVnFTbGRrVjBsNVVsaGtTV0ZIVGs5VVYzQktaREF4VlZOVVNrNVdSbFkyVkd0U1RrMHhaRzlaTURWUFVrZE9NMVJXVWtwTlozQk9Wa1pXTmxSclVrNU5NV1J4VVdwa1RsVnNSak5TVjJSYVVrWmFVbFZWZUVWUldGSkhXVzB4YTJOSFNuUldiWGhxWWxkNE1WZHVjRVpVUlRGQ1lUQmtRazFXVmtaUmJXaE9VVEZhVjFSWWFFZFNSVVpVUTJ0S2JsUnNXa05SVjA1T1VYcEdUMkZIU25WVmJXaEtVbFUxZWxkV2FFdGhSVEZTWXpOa1JGVldiRVZXYkVaU1UxVlNRbE5yVWxKV1JWWnRWRlZKZDFJd1JYaFdWVlpFV2pOa1dGVldaRk5OYkd4WVRsZHZTMWRzWkZKYU1WSllZa2R3YW1KVWFHNVZhMlJYVFcxR1dGUnRlR3BsYTFaVVZGVktRbEl3UlhoV1ZWWkNaRE5rUzFWV1drdFVSWGhXV2tkNGFXSlViRzlVVld4S1VUQnNjVkZWTlVOYU1uUjRZVWQwY0ZKM2J6Vmtla0pEVVZaR1JsSnJSa0pVTUU1Q1ducG9RbFJWYkVwUk1FNXVVekJPUWxvd1ZrSk5NRTVyVDFSV1ZFd3pWa2RVTTFaVFUxaE9jbFo2YkRKbGFteFhVa1ZLUjA1cWJFOVNSa1pIVG5wc2RsVnRhRTFEYVRsTlRXeENWMVZWWkc5VGVrNWFXa2RhUmxGdFpIZFNhVGxMWVZoa1dGSnJTbnBXUXpsdFYwVlNiMlZyUlhkTldFRjZWRWQwYWxaRE9ETlVSMUp4V1RGS2JWTXhhSEZUUjNkeVRVWkdlRXd3TURCYVJtOUxZVEpuTWxWVlVuWldWMVpNWldzMVExUkZVbXBSYTNSRlVrVmtXR0o2VGpKTmVsWlBaVmhLTkZsclJYaFNSelZ5VjFoa1ZsTXhWVEZSVlVaeVRrWkJOVTVJVWt4WFJYaDNUMFJDZG1WSVVUUk9SMFp2WlZGd1NXSXdlSFJaZVRsTlkxaE9TR016UVhKaU0wVjRVVzV2TUZWR1FucFhWWGd6VmtWak1HRlZNVXhXYlVab1ZrUnJkMHd5T1dGT1JXczBZakpzYVZVelNqRlBWRW95VTIxb2MyTldaRkJOYW1SclRERktORU50VFhwaFZsWk9aVmRvVDFwVlpGVmlNRGt5V2pObmRtRldWblpPUjJSSVkwVmpNazFWTlVWalIzUkdWbGhhU21WdVZreFpNa1pPWlVSb1NscEdVbmRXTW1ONVVrVlpNbFV6WkVkTlJXeHVWbXN4YlZwdE5FdGtibEpMWWxWRk1rOUZTak5UYXpWWVlucEdSazVHUWsxVGJWSm9WVWRhUTJGWFdtcFRia0l4VVd0YU0xUnNXbEpUVmtKU1VsWmFXVTB5UmxGUFJHeEpVMnhPZDA5R2JHbFhWR3h6WlZaT1ZFNXNRbk5XWjNCR1kxWlNRMUZ1VW1oVlZ6RndUa1ZHVlZJeU1VNVZhWFIxVFd0emRscFRkRXRSVjJoV1RXdGtjVTR5Y0VwalJYQnZWREowYTFORWJHMWhXRXBTVWtjMWRHSkZSWGxWTUZwdFUyazVSRmw2UW5SU01EVTJRMnhqTlZWdE1VcGhTR3hRVmxjMVQxSnRPV3BpUnpGeVZXMW9jMDE1T1VKVlZsVXhWMWhOTlZWWVRtaGlha1p4VmtNNVJtRlliRlZMTTBKRVkwY3hkVkZUZERWUFYxWnJaRzFvUlZFeVNsQlNlbWhIVFcwNFMyVkZhRWhWYlZKVlVXMTBOV0pJVm5WYU0wcHlWMFZ3U0ZkWGJETlNNMHBUVDBkMGFHRllSakpPTURWUFQwWkdiMVF3U2s1alZteHhXVEpLZVdFd1ZubE5SMWswVlZVeFRHRXllRXBWZWxaNVpGVTViV05SY0hOVVJURkVVVzVqTkZOcmVFTk5NSGh5WVc1Q1dGb3pVa1ZPTURsM1pVZDBObFV6VG5aaFJUUXdUakZXZG1KVVp6SlZiR3N5WWtoQk0wMXRZelJhVm1oSlZVUkdlRmRZU25Wa2JXZzJXVlZqZUZWNlkzZERibG96VG1zNWNsbHRSbWhSZW14R1lXMXNTVXd6VmtsYU1FWkxWVlZrTkdJeU5ETmtWRUpTVGpOb2JtSXhTa1pXTUVWMldsUmtTMWt3U2xKa01IaHVUMFJDU1dOVE9YcFpiRW94WTFkV2VtVkliek5rTUVsTFZqRk9XazFxVlRCWk1FNUNaREJXUWxGWFJrOUxNREZKWkROa1JWb3hiRVZXYkVsM1ZVVkdVbE5ET1VOUlZrWkZVVmRrUmxJd01VTk5SV1JDVFZaV2ExSkhaRkpXTUVwRFZUSmFXVnB0TkhKU1IxSnhaV2R3V0dSRlJqWlNNbXhaWkcxa1ZHSkdRakpoYTJSMlZqTndRbFZGU201VWJGcEpWV3N4UTFGWFdUUlNWVXBWVVZWU1FsVlZaM1pVVlZKMlVqQkZlRlpYVWtsa01VWTJWRlZTUm1Rd2R6SlJXRkoyVVROV1NFTnJkRmhoUkVKclUwVktObFF5YXpSa2JVVjVWVzV3YUZaNlZYZFhiV3N4WVVkS1dGVllWbHBOYW13d1ZFUk9ZV0ZzY0Zoak0xcHJZV3RXTWxWcVNsZGtWMGw1VWxoYVdrMHdjSHBVVlZaYVVqQk9WR05WWTB0Vk1HeHBUVEJTVWxKVlNrUmhhMFV4WWpCRk5HUXdVbEpYVlhCYVUxWndTbEZXWkZaU1JVcENVMVZPUTFWVlRtOVRSVkpDV1ZWS2JtRXpSbTloTW14SVQxaGpkMUZyUmxKYU0yUkZWVlpzUzFkVmJHRlRVWEJDVmpGV1JWRnJSa3BSTUVwU1VUSnNRbVF3YkVOVVZYUk9Va1ZHYmxKVlNrSk9SV3hFVVZaR1FscEZiSE5WUlVwRVRqQlNVbUpZV2tsT01uUnhZa1U1Tm1KcldqUk5NbXQ1VFZaT05sUXhRa1ZqZWxaTlEycGtWRm93V25GVVZVMDFZMnhKZDA1NlNUVk5hMlJTVVRCRk0xZHFaRlppU0VVMVRqQndVbGxXWkd4U1JFcDJXbXRrU0dNeVZURmpNMlJ4VGtVNVVscHJkRzFXYmxsMlpXMUdTMVpWV25Ga2JUbDZWMnM0UzJKdFdtRk9hazVzWTBoVk5GUlhjRmhhTUVwVVYwVndiazVXUmtaTU1FWnpUVWh3VTJNeGNIcGpSRlY2VWtWS1ZWcEZSWEpXV0ZsMlkzcE5lbHB0VmpSYVIxWjFWa1JHZEdORmRGcGxiV2hLV25rNWFsTjNjREJsYWxKMlZGaG9lRTlGY0V4V01HODBWVWM0ZUZFeGFFMWxhM1JxV201S1ZXTkhhSEZpUjBweVlVUm9RbFpyZEU1WFIxWkRXa1JLVkdORk1IcE5NRWw0VjFaQk1GcDZSa05VTWxKeVRVUkZlbUV6Um1sRGFtUnBWV3RvWVUxWGJFTk5hM0JKVW5wV2FsUlZkRXhaYm1SVFVURk9RbEZWWkVsVVJsSTJVVlpPYmxKSFRsbGphbXhIWTBSa1lVMHllSEJTUjJoSVpGTTVhbUZVUm5aalJXUjBZVE5CZUUxc1JrOWhWVzlMWkZWS2FXRXhVbFpMTTJoRlYydG9kRTVXWnpSVGJUQTFUMVZLV1U0d05VWmpTSEJ6VkROa1NsWnNTVFJSTW5odVVXdFNOV1JWU25KUmEwMTVZa2R3TUdOcVRtRlZNa1pXVTFac2NVMXVhREZsVm1SUFQxRnZNVk13V2xwT1JHeDFWak5vYW1WcWEzZFJNRnBvVFRCb05tSllhekJsYXpGU1lsVktiRTlYVWxkbFYzaDZUbGRXVFU1WVFUVlpiWFJaV1RKa1UxUlZVbFZaYldSMFZteHdjRkZYV1RCWlYxcHNUMFZTVFVOdFVuUlZWMDVhV1RBeFIxVlhTa2xoUjJSWFpXc3hjR1ZXY0VsU01IQnVXVEJPZVZWWE1VSk9NREZ5Vmtoa1JsTlhVbnBOV0dRMFREQm9ObFJYVGpOV1ZGSjRZMVUxUTFGWE9XRldhbVIyV2xWc1NsVklaMHRhU0VaSFYwZGFVV05WYUhoaFZrcHpVbGRLVTFKSFdsbE5WbEpJVGxVMVIxWnRSbXhSYm14WlRVVmtOVk5FV25GbGJHeFhaRmRXTmxKV1VqWmpibFpvWVROck1scHVRWGxaYlhkNVdXMU9ObVZHUWtaUFFYQkpXa1pOZWs5SGJIRmhWWEIwWWxSc01tSkVWWGRWYTJSV1dsVTVRbGRIY0ZSa1ZXeDFVakZKTUZsdVRsTmtWMXBzVWpGQ1EwOVlRbXhXUjBVMVVXMU9RMVF5VmxWV00zQjZaRWhHVlZaVlNYWlNhVGw0UTIxR1lWRXdiR0ZUTTBrd1YwUmFWV1ZYV2xaa1ZrNUZaV2s0ZUZOclVrSlNNbmR5WWtob2ExUlVRbEZQVTNSelZFZEdVVTlWTldoaFJrWnhVMFZPVjFwcVFqWmFha1pxVFZoT2FHSkdXakZTTUZweVRXNWpTMHd6WkU1bGFrWlRUVlZLU1ZwNk1EbERhVEIwVEZNd2RGSlZOVVZKUlU1R1ZXeFNTbEpyYkVSUlZsSkdURk13ZEV4VE1FdE1VekIwVEZNeFExSlZaRXBVYVVKRVVsWktWVk5WV2twUk1FWlZVbE13ZEV4VE1IUkRhekZLVTFWa2NGWkZUa1JSYTFKd1dqQkdNMU5WU2tKYU1HeEZVVmRrUWxFd01VWlhWV1JFVlROR1NGVXdiR2xOTUZKU1VsVktSR0ZyUlRGaU1FVTBaREJTVWxkVmNGcFRWbkJLVVZaa1ZsSkZTa0pUVlUxTFVXeEdSR0ZGYUVWUlYwWkRXakowZUdGSGRIQlNlbXd6VFVWS1FsVlhaRE5TUmtaYVUyeHNTbGRyYkVKV01WWkZVV3RHU2xFd1NsSlJNbXhDWkRCc1ExUlZkRTVTUlVadVVsVktUbE5JVGpSU2ExSkNWWGR3UTFvd05WZFJhMFo2VkZWTmQxWnVWbUZOYlhneFYyeGtWMlZYUmxoT1Z6Vk9WVmhPTTFFeFJscFNSbHBTVlZWa1JtUXdjRmRXV0hCR1ZsVXhRMU5WWkVKTlZsWkdVVzVrTTFSR1ZYbFNibFpyVWpCV2JrTnNSWGxsUjJocVlsVldORkV6Y0VKVGEwcHVWR3hhUTFGWFpFNVJWM1JQVVdzeFUwOUlaRWxWVm14RlZteEdVbE13VWtOWGEwcGhVMFp3YjFsdE1VOWlSbkJFVVdzMWFGWXdOVFZaYm14RFVsWndXVmR1UVV0WFZFcFhaV3N4VTFOWVpFWlJWbXhGVm14R1VsSkZVa0ppUlVwV1lUTk9NRlZxU2xka1YwbDVVbGhrU1dGSFRrOVVWM0JLWlVVeFJWUllhRTVXUlRFMlZGaHdVazVHWkc5Wk1EVlBVa2RPTkZSVlVrNWxRWEJPVmtVeE5sUlljRkpPUm1SeFVXcGtUbFZzUmpOU1YyUmFVa1phVWxWVmVFVlJXRkpIV1cweGEyTkhTblJXYlhocVlsZDRNVmR1Y0VaVVJURkNZVEJrUWsxV1ZrWlJiV2hPVVRGYVYxUllhRWRTUlVaVVEydEtibFJzV2tOUlYwNU9VWHBHVDJGSFNuVlZiV2hLVWxVMWVsZFdhRXRoUlRGU1l6TmtSRlZXYkVWV2JFWlNVMVZTUWxOclVsSldSVlp0VkZWSmQxSXdSWGhXVlZaRVdqTmtXRlZXWkZOTmJHeFlUbGR2UzFkc1pGSmFNVkpZWWtkd2FtSlVhRzVWYTJSWFRXMUdXRlJ0ZUdwbGExWlVWRlZLUWxJd1JYaFdWVlpDWkROa1MxWlVRbGRXTUhoV1drZDRhV0pVYkc5VVZXeEtVVEJzY1ZGVk5VTmFNblI0WVVkMGNGSjNielZrZWtKRFVWWkdSbEpyUmtKVU1FNUNXbnBvUWxSVmJFcFJNRTV1VXpCT1Fsb3dWa0ppTUdoTFlVaGFjazVGV2pOa01uUXpXV3BCZWxGVk1XMVVTR3hVVjBWd1ZGZEhNVVpaVlU1aFZGWlNVMWxyZUc1RGJFSm9ZV3BTZGxKWWNHaFNSR3d3VWpKYU5GRXhUak5NTWpWNlVUQkdjRmRGYUZKWlZtUldaRU56Y2xsdE5XbGhhM0JRVFVSV1ZWTXhVVEZhUTNSRVdraEtOazVET1cxaFZrcERZMGRLYjFwcVFqUmxibGxMWVVSRmVGUjVkRE5UYkZKRFZVZHZlbVJWVGpaU1J6QXdUMGhhUmxkcWFITk9WazVaVkZVNE1HUXlVWFpWV0VZell6TktiR0ZyV2taVmJFSkZUREJvYTFwdVdYaGlWV1JFVkZaak0xbFhUWGRrVjJNMFpFRndlVkpJY0hoU01sVnlZa04wZDA5Rk5VNWhia0YyVWxoR1ExSkdhM2xrYlZFMFlVVjRhRlpyZUhSVmVYUlpZV3RHZUdKR2JGZFViRXB5WXpKbk5WbFdValpWTVd4TlRWUnJkbGt4VW5sUmExSjBZMVpGZVVOdWF6Umhla2w2WldzMWMwMXRlRmhPYmtWMlVXNVNVbFF6UWxoU01WcDZUVEJXV0dSclNrbFphVGxTWW0xWmVscHFUbFJQVTNSelVYcFNTVTF0Y0d0U1NHczFaVmMwTTJFelJqVldSbVI0VGtaa1JGRnRORXRTVkZKNFlVWnNTMVZ0T1hKa1YzaGFaRWh3VGxkck1IaFRWM2h5VGtadk1sVnNRbkpVTVZKVFRWVXhTMDVIWkd0U2JsSnhUako0VEdKWVNuSlZNMVpRWWpCd1dtSllSbTlUYTJ4NlZWVnZORTVVVW5OUlVYQnBVMjVzYVZveFZUTmxibXcyVmpCR00yUlVUakZaV0U1ellURnNURlpWVmtKVlYxbDVZVzFGTVZOSWJITk5NR3hEWTFVNU5tTklSbHBOZWtaVVkwVjBObGx0ZHpSVWJHZ3lXbFp3TlZsc1NrNWhNbmd6UTIxYWJFNUhiRVZVUld0NVRsWlJOV0V6VlRWUk1WcHNaRVZTV21GWFdrUlpiVkpJV2xoV1NWcEdVak5YYTBwRFdsY3hXRTVGTlVaT1ZHUk5UakpzUmxacVozSmxibTgwWW01b2RWcDZhRkJVVm1kMlRIcFJTMk5HYUhWa1JtUjRZbFpHYVZKVlJuVlJhM2d5VFd4U2RsWkhaR3ROVldkNVpXeHNVMlJIYURWU1JYaHFUVEZaZUUxVWEzWkxNRnAxVmtaamVFNHdlRXhPYlVwTVpXeFNSRm93Vm5WUk1HaFNVbGRPUW1SQmIzZGhSVkpTVkVWNFIwNTZhelZMZWtwelYyeFNOR1ZIV2tOU1Z6bHJaRlZHWVZsWVp6SlRWM0J1VVZVeFJHRlVXbXhOVm5CdFV6RkNTMVV5ZEd0a2JVbDVZbFJPUTJReVdsRlBSMHAxWVZWak0wc3dSa1pEYTNBeVRWWmtVRkpYTVhWUmEzQnFUVmhDVjFWVlRqQmtSMHBMVmxjNWExbHRhM2RPTVZwdFdsYzBNVk5zU2xaalZVWXlWVEF3ZWxReVNsaFZWVGsyVlRCR1NHVnVUa2hpYmtKS1lWZGtNMUp1UWxoT2JUQkxUMVZaTTJSV2JGZFdWVTVDWkRCV1FsRlhSbEJSYlRrMlVUQktkbEpGUm10UmJXUlBWbXRvVWs1RlZrZGFNVVpXWXpOT1lVNHpRa1ZXZW1SSlUyeGFjbE5GUm5SYU1VWnRUREJaZWxKWE1VaFNiRnAyWkhkd1NXUXhiRVZXYkVsM1lXdEtRMW96WkVkaU1FWldZbXBGZWs1VE9XNU5NV3MwVFZoS1VsUllhSFppUkdNd1VsaENWVTU2VWpSalZWcDZaREJXYmxkVlVsZFZha0pWVVZaR1NVd3dTa0phTTJSRFdqQldRME5wT1ROVFZVcENVa1ZHVUZGdFpFOVdhMmhTVDBWS1FscHFhRVpSYTBaT1VUQkdVbFZZWkZCYU1XeEZWbXhKZDFwclNrVlVXR1JPVmtWR01tSXdUWGxhTUhNd1YxaENhRk5HU1hkWk1HaE9UbXQ0TlU5WVNVdFhhMmhQWTBkS2RWVnRNVTFpVlZvd1YydE5NV0Z0U1hsTlNGcHJZbFUxYzFsWWF6Vk5hekZVVDFWb1lWWjZWakpYVmswMVlXMU9kR1F6WkZOYU1XeExVekk1WVZOWGFESlpNRFZDVlZWV1RGUlZVblJhZDNCRlpXdEdUMUZ0WkhOYU1taHlXakJLWVZWVk1VWlJWMlJLVW10R1RGSlhUazVSYlRsSVVURk9lRkl4VGtwWmFrNUZWVlZXUTFFd1VrSlVhMHB1WWtka2IyRXlaRU5YYkVaT1VsVkdibE5WV2tKVE1HeEZRMnRHYmxKWVpIWmtNREZFVVZaR1JsSkhaRzVUVlVwQ1UxZGtNVTB4V1hsa1JrWkxWREk0ZDB4NldraGthelYwWkRCNFdWbHJlRVZqYms1TlV6Rm9lRk5HVm5oYVJXUTFWREZ3Vm1OR1FrbFVWRTR4WVd4UlMxbFhWalJOVldOeVQwZEtSbG93U25wa00yUkRXVk4wTTFSdVduTk5WazVTWTFaS2VHVlVTalJOYkVZelZVTjBjRXg1T1VOWk1XUjVUVEo0VG1Oc1ZqUlpNbXN3VW5wamRsVkVhRzlYYTBwWFQwUkplR0puY0hsUlZsWmhaRWRLTWxwdVJuTlpWRlpPWTJ4S1NVOVZSa3hUYkdoWVZuazVkMkpZVW10TlZFSnFaVzVHUkZOSGREWmFSWGhTVkd4d1QyRnVVWGxhUnpWaFUwVXhVbEZWTVRCU00wMTRVVmhTTldKc1NrWkRhMmhQWkRCV1EyRlZaM2xUTUVZd1RqSmtWbGw1T1hwVE1XUjFWVEJPY0dOSWNEQlRNRlV6VG01Q01WUnBPVmxYUjBwVVpVTjBXR041ZEZkVlIyeEhaSHBhUkZGclJteFRWR3hyWTFjMVJtRldSWGhrU0VGTFVsZGtlR1JHWkVaa1IwNU1ZbFJrU0ZveVNYaFhSV2N5WWpGa2FWTldUblppTTJReVdYcEJkMHd3UmtWV01scFBZakl3ZDJWSGR6Smtha3BFVG14S1NsWXhiRzVXVnpsaFRXMVpNMVZGVGpWV2FrNUZaRUZ3YVdSVE9XMVZWMW8xWlZad01tSllVbGRVUlVVd1dqQkplVkpYYUdwT2F6bDBZVzVyZVUxV2F6Rk9WbVJhVDFWc00xcFZhSE5UTUZaUFZGWkNSbFpXV2pCVmJrWlFaR3hLVjFOVVFuUmlSR3hZV1cxR2MwTnRXWGRPUkd4eFlqQk9NVTF0YjNwTk1XaFJZMWhrZDAwd2JIbGxiVll5WWxaQ1ExSkZaSGRWYWtwVVpFZFNkRTB3Y3pKT2JVVjJXbms1UTFVeGF6TldNazAxVERGYWJHVlhkRkZOTVVwWllraG9XazFXVVV0VVZURkxUMFZaZUdKSVFtNU9iRkowWkZOMGFrc3pXblprZW1ScVlrZHNOV05WT1haWldHeENZbXhKTTAxV1ZUUkxNMHBZWTJ0M2VsTkdTa2xoUjFaVVZteG5ORkl4UWxwVU1rWkZWR3RLVldSRVozcE5VWEJoVFVSSk0yUnJVbGhrYWswMFRWUkdNbFJYT1RSWFdHaHZaRlpTVTFsWE9YSmthelZZVVRGT05tSlZiM2xTVm1SNVZVWnNTVmt3YUZCa1IzUnhWVEJhVEZScVpIWmtSRUpUV1hwamQxcHJiRk5YYTFaYVEyMU5lV050U1hwbFdHUk5WVEpzYWxKWVJYcFRiRVpFWW0wMU5rNXRiRVJYYWtZd1ZGZGFkMkpJY0dwamEyOTVWRWMxV0UxcldYaFJlbWcxVld4WmNtSXlkRFZpU0d4UVZXMTRlbGxZYUZCVVJYUmFWREZqUzJGdFJrVldSazVIV1ZoRmVGUnJiRE5pTWxKSlkwUmtXVTlYV2xCU2VsRTBaRlpLTVZOc1pGUlBSV1IwWVZkYVJVOVVXVFZqTUUwd1ZsaFJlVkpyY0VkaU1uUnpXVEpXUTFac1ZrOVJNR2hUUTJrd2RFeFRNSFJTVlRWRlNVVk9SbFZzVWtwU2EyeEVVVlpTUmt4VE1IUk1VekJMVEZNd2RFeFRNVU5TVldSS1ZHbENSRkpXU2xWVFZWcEtVVEJHVlZKVE1IUk1VekIwUTJzeFNsTlZXbEZsYTA1RVVWaGFVRm93UmpOVFZVcENXakJzUTFGVlVrTlJhMHB1WVROR2IyRXliRWhQV0dOM1VXdEdVbUl6WkU5VE1FWlJWRlZGZDFJd1RsaFJNR1JVVVZWYWMxRllaRkpSTUVadVZsVkZTMkl4U2pOa01HUnVWMVZ3VEdJeGNFcGhTRnBxVkd0R1VsSlZiRTVSVkVKSVVURmtSRkl4VGtKU2JYaENaREZHUkZGWFpGWlJWemx1VkZWT1FsWkZSak5hV0hCR1ZsVXhRMU5WWkVKTlZsWkdVVE5rTTFSQmNGTldlbFoxV1Zaak1XSkdjRmxUYmtKcFlsZE9ORkV6Y0VKVGEwcHVWR3hhUTFGV2JGVlJWM2hYVmtVeFUxVllaRVphTVd4RlZteEdVbE5GVWtKa1JsSmFWbnBWZDFkV1RrTlNSMHBJVW01c1dsWkZWazFEYXpGQ1lUQmtRazFXVmtaUk1FWXpVVEZGZDFKWWFFbGxhMFpyVVcxa1QxWnJTa0ppTURGSFlUQmFjbHBITVVka1ZtdDVWbTEwU2xKVVJuZFhWRTVMWkd0c1JsVnRlR3RpVjNoeFYyeG9UbVZGVm5GUlZrVkxVVzFrVDFaclNrSlVWVEZFVm1zMVIxWnRhM2hUUm5CWVRsaGFXbFpGUm14U2JtTjNaVlUxVlZGVVFrNWhhMFkwVkRCU1RtVkZNVFpYYlVaSFpIcENObFJYY0VKTlJURnhVVmhvVUZKRk1UUlVXSEJoV1ZGd1RsTkhPVFJTYTFKQ1ZUQktibFJzV2tOUldFNU9VWHBDVjJSV2IzbGlTRlpoVmpGYU5WbFdZekZpYXpGU1l6TmtSRlZXYkVWV2JFWlNVakJXTTFOc1dsWmxhMVpXVkZWS1NsSXdSWGhXVlZaRFpETmtUVU5zVlhsU2JsWnJVakJXYmxWVVNqUmhSMDUwVWxob1JHVnJSa3RSYldSUFZtdEtRbG93TVVKaE1EVkRWRlpKTkdRd2FGSlhWVkpYVlZaR1RGSkZTbUZSYkhCSlYyMW9hV0pWTlhOWGEwNURWRzFHV0ZSdWEwdFpibXhEVWxad1dWZHVRbHBOYkZvMlZGWktSbVF3VWpOWFZWSlhWVlpHUlZKRlJtOVdSa3BYVjFoU1YyRXdOVWRWTTNCRFRXc3hRMUZWWkVObFdFWklWVEF3TUU5VlJtNVNWV1JEVlROV1ExRnJSa0poVVhCQ1RXdHNRbEZyTVRCV2JrWlVZMnQwV0dJemNEVmhNSGhEVFZWc1JVOUZhREpoYlRWUlZtNWFTbUV3VWxsV1ZFSnJZVzFrU0ZFeFNtaGFSVVpxVkdwWk5VNUdTbFJVU0dRMlRXNWtNbUZzYUZSVWVrNXJRMnhrZFZKVGRITmFSbkF3VjFkb1ZXSnVVVEJoVjFwTVltMW5kMlZHYkVkYVZXTjZaRlpLVUZwVVNsRkxNV1JJVVcxck5GTnJSWGhWYTNSd1VXMVNZV1ZWU2s5a00xWk9VV3RuZW1OcVJrMVZWVFY0WTFVNFMyRkVXbEphUlRsb1ZEQk9RbFZyTVROYU1tUkdWVVV4UTFGVlpFUlZNMDVJVVZaR1VsRnROVWxhTUVwQ1ZWWkdSVkZYWkVaUlZURkRWVlZrUkZVelRraFJWa1pTVVcwMVNWb3dTa0phTVVaSlVtMWtWMU5CY0dGV2VsWXlWMVpTUWxWclNtNWlNMHBEV2pCV1JsRldjRFJPUlVaU1ZGVktRMUZWTVVSUlZrWjJaREJXVWxkVmRFeGtNV3hEVVd0R1NGa3lWa0pTVlZKQ1dqRkdSVkZYWkVaUlZURkRVbFZrUkdGWVRraERhMFpTVlZWS2RWTkhaRU5SV0dSU1VsVkdNMU5WU2tKU1JVWlRVVzFrZG1OclNtNVNWVlpDVjI1bk1GRldSazVTYTBwQ1ZGVk9RbFZWUmpOU1ZrWmFVekIwTTFkVlNrTlJWV1JxV2xWR1JsSkZTbTVWVlZGTFVWZGtSbEZWTVVOU1ZXUkVZVmhPU0ZGV1JsSlJiVFZKV2pCS1FtUXlUa1pSV0dSS1VXdEdSVkZXU2tOYU1qbDVVVzFrUmxKVlJtRmxSRkpDVlZVeFJWRnJSazVSTUVaVFdUTmtSbFZXYkV4VE0yUmFVV2R3UTFGVlpHcGFWVVpHVWtWT1FsVlZVa0phTUZwV1ZGVlZkMUl3VGxSak1HUkNWVlpHUTJKcmFHNVJhMHBDVld0R2JHVkdaRVpsVmxZMFRteEdkRkp0ZEhwa1NFNVRZbFZ3UWs5WVRraGhSMHB0VFZNNWFFTnVXbTFWV0ZKVldWY3hRMk13TkRGVk1HaFRUVmRTV1ZkWVJsTmhNMnd4VGpOa2FWSlRPVmxXYm13eFZXMUdhbVF4U25OYWJIQjRXa1ZHYWxaVk1WSk5WbkF6VDBWYVdtTldaRmxSTTNCRFVXdEtibUV6UlV0aFIzUndVbnBzTTAxRlNrSlZWemt6Vkd0MFFsVkZNVUpOUldSRVZqQk9TRlV3UmtkaVJVWXpWVlZPUWxveFZrSmlNVW96WkRCa2JsZFZjRXhpTVhCS1lVaGFhbFJyUmxKU1ZXeE9VVlJDU0ZFeFpFUlNkM0JVVVZWYWMxRllaRkpSTUVadVZsVkdkbG93TVVSUlZsSkNVa2RrYmxOVlNrSlRSMVV5VXpCUk5GSXpjSE5OVm1oMlYwaHdUVTlITURSbFJFNUZXbGQwU2xaNmFIWmliV1J5WkVoR2VWZElVWGxSTUdodlEydEtVMUpHYkZsa01scE1XbTVvUlU0eVpEWlhWV1IyVW0xR1NsUlZTbHBoVjFwb1ZHazVORnBxVWtaTE1FNVdXbXhaTVdKNlVreFVWRnBzVVZSQ1lXVllUakpOYTFKSllWYzFkMVpHY0RaaGFtUllaRzA0UzJRd1ozSmhNWEIyWXpGV2FtUkhWblZPVjBaMFVrVXdlazFYVFhsWk1ERXpZV3RKZGxacVdrZGpNWEJwWWpCV1VGWXlPVU5rTTJzeFZIazVTbFJYVW14TlZURlFZa2MxVm1OdGFHaE5iRVp3VjIxV2NGbG5jRVpaVmxKUVZqTm9NMVZUT1ZGVFZVNXFUakJLTkdGRE9EUlZSWEJPWlZWa2QyVllSbFprVlZaS1ZEQk5NV0ZyWkZST2Exa3pWVlUxVkUwd2VIcE5XRkowVFhwa2RWVkZOVXRXZWtKUFdqQkpNMk13Wkd4RGJGWnhZMWRzTms5VVRtNU9NMFphVFROYVdrNXNaekJUUjBvMVVUSTBNVll3Y0U5aVZsWkZVMVpzV2xadGVGSk5TRUpvVGtaV1RsSlZPREpSVjNCTlVsZFdNVmRIYjNKUmFUbEhZek5LVEZreGNESmtNRzlMVFhrNWNGTnFTbTlrV0VweVUwVmtSMVZ0V25aTlZYQkRXa1ZzYWxKWFJsQlRNakUyVlVobmNrMXRUa3BsYTBsM1VWUnNOa3d3YTNaaU0wNTZWVk4wZGxkcldsUmpWR00wVkVkWk5HVnVUbTVqYTNoeVZuZHdZVlZGVG0xT2FrNVNaV3RhYUZsdFJsWk9hazVvWTI1c1YxRlhXbGxOVjFKRlZHdFdTRXd5TUROVE1HOHdUVzFWZWs5SFRuVlVSbkJEWkRBMWNGVkZjM2RoYWtwMlpEQTFRbGRVU1RKVWEzaFlUVlZqZVVOdFRsUlRWRUY1V210amVsWjZWbTFaYVhSaFkzcG9SMUZZWnpOUk1IaGhUVEZvZGxKVGMzcE5WMmhXVjFkak5XUjZUa1JoVm5CUlVsWkdlVlY2YTNkTU0wSTBaVWhvYW1Kck9WcGlSVTVGVkVVeE5sTkVRVXRTYTJSR1ZqQjBSbUp1U2paWmFtZDVWVzB4YzFSc1FscE5XRlowV2pORk1Wa3pXbGxXTVU1WlRtMWtkRmt4U2xCWFZVcFhUVlpDTmt3eVRqQmhXSEJWWVRGV1JsRXhTbWhQUjNjeVRWWk9NRmxXU20xalFYQlZaVlJhZGxKcmR6RlpWbEkwVVZaWmVsVnJlRWhTVjBrd1pHNXNObVJGV25OVlZGRXdUVlpXWVdGck5WQlZNalUxVERCNGVWb3lkM1poTW1SUVVXdDNORkl3VG1Ga1ZFcHZXVE5PYVdWc2JEUmlSMmN5UTIxd1IxWkZWa05UVld0MlZsZEdlbUV6UWtWak1HUjBaSHBzTWt3eFZtcFZTRVpzVlhwT1ZXRlVhRUpUYmxKaFl6TmtRMU13TURGWFIxWTJWWHBTVUUxc2JIWldiR3hIVTFkb1dsZEVTalJPTTFwMFlURnJTMDB3WkZWamQyOTBURk13ZEV4VlZrOVNRMEpFVWxaS1ZWTlZXa3BSTUVaVlVsTXdkRXhUTUhSRFp5SXNJbTkxZEdKc2IySWlPaUpCZDBGQlFVRkJRVUZCUVVGQlFVMUJRVUZCUVVGQlFVRkJRVUZCUVVGQlFVRkJRVUZCUVVGQlFVRkJRVUZCUVVGQlFVRkJRVUZCUVVGQlFVRkJRVUZCUVVGQlFVRkJSVUZCUVVGTFFVRkJRVUZCUVZoV1ExVkJRVUZCUVVGQlFVRkJRVUZCUVVGQlFVRkJRazVUVlZKRFZHdG5lVTlIYkhCaU1teDZZV3hDTldWSWFEUmxTR2cwWlVob05HVklhRFJsU0dnMFpVVXhTbEpGU2s5VFJFazBZVmRzZG1GWVRuRlZTR3cwWlVob05HVklhRFJsU0dnMFpVaG9OR1ZJYURSa2NHNXRja0pNVFRNNVNHWnlTRVJ0VTJNMFprSkhlWGx5TjNOQlRrUnFNSHBrTXkxTVRYWm9aM1p3WmkwdGFtTXlOVTFGVmtSS1QwVk5WWE5sU1cxQlFVRkJRVUZCUVVGQlFVRkJRVUZCUVVGQlFVRkJRVUZCUVVGQlFVRkJRVUZCUVVGQlFVRkJRVUZCUVVGQlFVRkJRVUZCUVVGQlFVRkJRVUZCUVVGQlFVRkJRVUZCUVVGQlFVRkJRVUZCUVVGQlFVRkJRVUZCUVVGQlFVRkJRVUZCUVVGQlFVRkJRVUZCUVVGQlFVRkJRVUZCUVVGQlFVRkJRVUZCUVVGQlFVRkJRVUZCUVVGQlFVRkJRVUZCUVVGQlFVRkJRVUZCUVVGQlFVRkJRVUZCUVVGQlFVRkJRVUZCUVVGRFJHWXRZbXgzZDBONVVrVmhNR2RQV2pSWE1HeElVeTF3TVdvMVowZFlPVzFGWDFkNmRsQm5RbTlFWDE5ZlgxOWZYMTlmWDE5ZlgxOWZYMTlmWDE5ZlgxOWZYMTlmWDE5ZlgxOWZYMTlmWDE5ZlgxOWZYME5uUVVGQlFVRkJSakZSV2tWUlJVRkJRVUZCUVVGQlFVRkJRVUZCUVVGQlFVRkJRVUZCUVVGQlFVSTNSbGxVU2xSSWNFTlpWMU41TW5oSFdXdEVNbmRoUm5SZldEbHhPVGxETVU1eFdVZDNNMnhKWkVoV01XUnBjRWRVU3pkMlFuTlVPV1JZU3pWR2NIcENSMVk1YlhBd1FuaFJlRVJXYmtSM1ZtbHdXbU5NUTJkQlFVRkJRVUZHTVZGdlRuZEZRVXRFWTBKQlFXOUJRVUZCUVVGQ1pGVkJRVUZCUVVGQlFVRkJRVUZCUVVGQlFVRkJRVUZCUVVGQlFVRkJRVUZCUVVGQlFVRkJRVUZCUVVGQlFVRkJRVUZCUVVGQlFVRkJRVUZCUVVGQlFVRkJRVUZCUVVGQlFVRkJRVUZCUVVGQlFVRkJRVUZCUVVGQlFVRkJRVUZCUVVGQlFVRkJRVUZCUVVGQlFVRkJRVUZCUVVGQlFVRkJRVUZCUVVGQlFVRkJRVUZCUVVGQlFVRkJRVUZCUVVGQlFVRkJRVUZCUVVGQlFVRkJRVUZCUVVGQlFVRkJRVUZCUVVGQlFVRkJRVUZCUVVGQlFVRkJRVUZCUVVGQlFVRkJRVUZCUVVGQlFVRkJRVUZCUVVGQlFVRkJRVUZCUVVGQlFVRkJRVUZCUVVGQlFYVnFXak5ZYmxOUVdHVlJRVGRTUnpCbk4xSm9hV1JqWkhWb2JWcFZlbGR5ZWs0M2RXSndSR2hqZEZSV09HaG1WM1oyYVVzMmRYY3pTRlpGYnpreGEyRkJRVUZCUVVGQlFVRkJRVUZCUVVGQlFVRkJRVUZCUVVGQlFVRkJRVUZCUVVSbVJ6QXRjMFZuWldjM2J6Um9lRk5xYTFOaGNXTTBTRGhwT1dseVJYTTNZV0paUVhOa1psbHBjMVF3TjJsQmVtOVdMVzR3YUd0RWFrWjRWRXhMT0VWQlFVRkJRVUZCUVVGQlFVRkJRVUZCUVVGQlFVRkJRVUZCUVVGQlFVRkJRVUZCUVVGQlFVRkJRVUZCUVVGQlFVRkJRVUZCUVVGQlFVRkJRVUZCUVVGQlFVRkJRVUZCUVVGQlFVRkJRVUZCUVVGQlFVRkJRVUZCUVVGQlFVRkJRVUZCUVVGQlFVRkJRVUZCUVVGQlFVRkJRVUZCUVVGQlFVRkJRVUZCUVVGQlFVRkJRVUZCUVVGQlFVRkJRVUZCUVVGQlFVRkJRVUZCUVVGQlFVRkJRVUZCUVVGQlFVRkJRVUZCUVVGQlFVRkJRVUZCUVVGQlFVRkJRVUZCUVVGQlFVRkJRVUZCUVVGQlFVRkJRVUZCUVVGQlFVRkJRVUZCUVVGQlFVRkJRVUZCUVVGQlFVRkJRVUZCUVVGQlFVRkJRVUZCUVVGQlFVRkJRVUZCUVVGQlFVRkJRVUZCUVVGQlFVRkJRVUZCUVVGQlFVRkJRVUZCUVVGQlFVRkJRVUZCUVVGQlFVRkJRVUZCUVVGQlFVRkJRVUZCUVVGQlFVRkJRVUZCUVVGQlFVRkJRVUZCUVVGQlFVRkJRVUZCUVVGQlFVRkJRVUZCUVVGQlFVRkJRVUZCUVVGQlFVRkJRVUZCUVVGQlFVRkJRVUZCUVVGQlFVRkJRVUZCUVVGQlFVRkJRVUZCUVVGQlFVRkJRVUZCUVVGQlFVRkJRVUZCUVVGQlFVRkJRVUZCUVVGQlFVRkJRVUZCUVVGQlFVRkJRVUZCUVVGQlFVRkJRVUZCUVVGQlFVRkJRVUZCUVVGQlFVRkJRVUZCUVVGQlFVRkJRVUZCUVVGQlFVRkJRVUZCUVVGQlFVRkJRVUZCUVVGQlFVRkJRVUZCUVVGQlFVRkJRVUZCUVVGQlFVRkJRVUZCUVVGQlFVRkJRVUZCUVVGQklpd2ljSEp2ZG1sa1pYSWlPaUp6WlhaZlozVmxjM1JjYmlKOSJdfQ==","eat_nonce":"TUlEQk5IMjhpaW9pc2pQeXh4eHh4eHh4eHh4eHh4eHhNSURCTkgyOGlpb2lzalB5eHh4eHh4eHh4eHh4eHh4eA","eat_profile":"tag:github.com,2024:veraison/ratsd"} diff --git a/scheme/sevsnp/test/sevsnp-tsm-report.cbor b/scheme/sevsnp/test/sevsnp-tsm-report.cbor new file mode 100755 index 00000000..47908bb2 Binary files /dev/null and b/scheme/sevsnp/test/sevsnp-tsm-report.cbor differ diff --git a/scheme/sevsnp/test/sevsnp-tsm-report.json b/scheme/sevsnp/test/sevsnp-tsm-report.json new file mode 100644 index 00000000..0e39273f --- /dev/null +++ b/scheme/sevsnp/test/sevsnp-tsm-report.json @@ -0,0 +1 @@ +{"auxblob":"wLQGpKgDSVKXQz-2AUzQrmAAAADlCAAASrezebusT-SgLwWu8yfHgkUJAAAVCQAAY9p1jeZkRWStxfS5O-iszVoSAABXBwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAALS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUdZekNDQkJLZ0F3SUJBZ0lEQWdBQU1FWUdDU3FHU0liM0RRRUJDakE1b0E4d0RRWUpZSVpJQVdVREJBSUMKQlFDaEhEQWFCZ2txaGtpRzl3MEJBUWd3RFFZSllJWklBV1VEQkFJQ0JRQ2lBd0lCTUtNREFnRUJNSHN4RkRBUwpCZ05WQkFzTUMwVnVaMmx1WldWeWFXNW5NUXN3Q1FZRFZRUUdFd0pWVXpFVU1CSUdBMVVFQnd3TFUyRnVkR0VnClEyeGhjbUV4Q3pBSkJnTlZCQWdNQWtOQk1SOHdIUVlEVlFRS0RCWkJaSFpoYm1ObFpDQk5hV055YnlCRVpYWnAKWTJWek1SSXdFQVlEVlFRRERBbEJVa3N0UjJWdWIyRXdIaGNOTWpJd01USTJNVFV6TkRNM1doY05ORGN3TVRJMgpNVFV6TkRNM1dqQjdNUlF3RWdZRFZRUUxEQXRGYm1kcGJtVmxjbWx1WnpFTE1Ba0dBMVVFQmhNQ1ZWTXhGREFTCkJnTlZCQWNNQzFOaGJuUmhJRU5zWVhKaE1Rc3dDUVlEVlFRSURBSkRRVEVmTUIwR0ExVUVDZ3dXUVdSMllXNWoKWldRZ1RXbGpjbThnUkdWMmFXTmxjekVTTUJBR0ExVUVBd3dKUVZKTExVZGxibTloTUlJQ0lqQU5CZ2txaGtpRwo5dzBCQVFFRkFBT0NBZzhBTUlJQ0NnS0NBZ0VBM0NkOTVTL3VGT3VSSXNrVzl2ejlWREJGNjlORFFGNzlvUmhMCi9MMlBWUUdoSzNZZGZFQmdwRi9KaXdXRkJzVC9mWERoekEwMXAzTGtjVC83TGRqY1JmS1hqSGwrMFFxL000ZFoKa2g2UURvVWVLek5CTERjQktEREdXbzN2MzVOeXJ4YkExRG5rWXdVS1U1QUFrNFA5NHRLWExwODBveHQ4NGFoeQpIb0xtYy9McXNHc3Arb3ExQno0UFBzWUx3VEc0aU1LVmFhVDkwL29aNEk4b2liU3J1OTJ2SmhscVdPMjdkL1J4CmMzaVVNeWhOZUdUb092Z3gvaVVvNGdHcEc2MU5EcGtFVXZJenVLY2FNeDhJZFRwV2cyREY2U3dGMElnVk1mZm4KdnRKbUE2OEJ3Sk5XbzFFNFBMSmRhUGZCaWZjSnB1QkZ3TlZRSVBRRVZYM2FQODlISlNwOFliWTlseVNTNlBsVgpFcVRCQnRhUW1pNEFUR21NUituMksvZStKQWhVMkdqN2pJcEpoT2tkSDlmaXJRRG5tbEEyU0ZmSi9DYzBtR056Clc5Um1JaHlPVW5ORm9jbG1rUmhsMy9BUVU1WXM5UXNhbjFqVC9FaXlUK3BDcG1uQSt5OWVkdmhEQ2JPRzhGMm8KeEhHUmRUQmt5bHVuZ3JrWEpHWWl3R3JSOGthaXF2N05OOFFoT0JNcVlqY2Jya0VyMGY4UU1La2xJUzVydU9mcQpsTE1DQnc4SkxCM0xranBXZ3REN09weGt6U3NvaE40N1VvbTg2Ulk2bHA3Mmc4ZVhIUDFxWXJudmh6YUcxUzcwCnZ3Nk9rYmFhQzlFamlIL3VIZ0FKUUd4b243dTBRN3hnb1JFV0EvZTdKY0JRd0xnODBIcS9zYlJ1cWVzeHo3d0IKV1NZMjU0Y0NBd0VBQWFOK01Id3dEZ1lEVlIwUEFRSC9CQVFEQWdFR01CMEdBMVVkRGdRV0JCU2ZYZm4rRGRqegpXdEF6R2lYdmdTbFB2akdvV3pBUEJnTlZIUk1CQWY4RUJUQURBUUgvTURvR0ExVWRId1F6TURFd0w2QXRvQ3VHCktXaDBkSEJ6T2k4dmEyUnphVzUwWmk1aGJXUXVZMjl0TDNaalpXc3ZkakV2UjJWdWIyRXZZM0pzTUVZR0NTcUcKU0liM0RRRUJDakE1b0E4d0RRWUpZSVpJQVdVREJBSUNCUUNoSERBYUJna3Foa2lHOXcwQkFRZ3dEUVlKWUlaSQpBV1VEQkFJQ0JRQ2lBd0lCTUtNREFnRUJBNElDQVFBZElsUEJDN0RRbXZIN2tqbE96bkZ4M2kyMVN6T1BEczVMCjdTZ0ZqTUM5clIwNzI5MkdRQ0E3WjdVbHE5N0pRYVdlRDJvZkdHc2U1c3dqNE9RZktmVnYvemFKVUZqdm9zWk8KbmZaNjNlcHU4TWpXZ0JTWEpnNVFFL0FsMHpSc1pzcDUzREJUZEErVXYvczMzZmV4ZGVuVDFtcEtZemhJZy9jSwp0ejRvTXhxOEpLV0o4UG8xQ1hMektjZnJUcGhqbGJraDhBVktNWGVCZDJTcE0zM0IxWVA0ZzFCT2RrMDEza3FiCjdiUkhaMWlCMkpIRzVjTUtLYndSQ1NBQUdITFR6QVNnRGNYcjlGcDdaM2xpRGhHdS9jaTFvcEdta3AxMlFOaUoKdUJia1RVK3hEWkhtNVg4Sm05OUJYN05FcHpsT3dJVlI4Q2xnQkR5dUJrQkMybGp0cjNaU2FVSVlqMnh1eVdOOQo1S0ZZNDluV3hjejkwQ0ZhM0h6bXk0ek1RbUJlOWRWeWxzNWVMNXA5YmtYY2dSTURUYmdtVlppQWY0YWZlOERMCmRtUWNZY01GUWJIaGdWek1peVpIR0pnY0NyUW1BN01rVHdFSWRzMXd4L0h6TWN3VTRxcU5CQW9aVjdvZUlJUHgKZHFGWGZQcUhxaVJsRWJSRGZYMVRHNU5GVmFlQnlYMEd5SDZqellWdWV6RVR6cnVha3k2ZnAyYmwyYmN6eFBFOApIZFMzOGlqaUptbTl2bDUwUkdVZU9BWGpTdUluR1I0YnNSdWZlR1BCOXBlVGE5QmNCT2VUV3pzdHFUVUIvRi9xCmFaQ0laS3I0WDZUeWZVdVNEei8xSkRBR2wrbHhkTTBQOStsTGFQOU5haFFqSENWZjB6ZjFjMXNhbFZ1R0ZrMncKL3dNejFSMUJIZz09Ci0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0KLS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUdpVENDQkRpZ0F3SUJBZ0lEQWdBQ01FWUdDU3FHU0liM0RRRUJDakE1b0E4d0RRWUpZSVpJQVdVREJBSUMKQlFDaEhEQWFCZ2txaGtpRzl3MEJBUWd3RFFZSllJWklBV1VEQkFJQ0JRQ2lBd0lCTUtNREFnRUJNSHN4RkRBUwpCZ05WQkFzTUMwVnVaMmx1WldWeWFXNW5NUXN3Q1FZRFZRUUdFd0pWVXpFVU1CSUdBMVVFQnd3TFUyRnVkR0VnClEyeGhjbUV4Q3pBSkJnTlZCQWdNQWtOQk1SOHdIUVlEVlFRS0RCWkJaSFpoYm1ObFpDQk5hV055YnlCRVpYWnAKWTJWek1SSXdFQVlEVlFRRERBbEJVa3N0UjJWdWIyRXdIaGNOTWpJeE1ETXhNVE16TXpRNFdoY05ORGN4TURNeApNVE16TXpRNFdqQjdNUlF3RWdZRFZRUUxEQXRGYm1kcGJtVmxjbWx1WnpFTE1Ba0dBMVVFQmhNQ1ZWTXhGREFTCkJnTlZCQWNNQzFOaGJuUmhJRU5zWVhKaE1Rc3dDUVlEVlFRSURBSkRRVEVmTUIwR0ExVUVDZ3dXUVdSMllXNWoKWldRZ1RXbGpjbThnUkdWMmFXTmxjekVTTUJBR0ExVUVBd3dKVTBWV0xVZGxibTloTUlJQ0lqQU5CZ2txaGtpRwo5dzBCQVFFRkFBT0NBZzhBTUlJQ0NnS0NBZ0VBb0hKaHZrNEZ3d2t3YjAzQU1mTHlTWEpTWG1FYUNaTVRSYkxnClBhajRvRXphRDl0R2Z4Q1N3L25zQ0FpWEhRYVdVdCsrYm5iakpPMDVUS1Q1ZCtDZHJ6NC9maVJCcGJoZjB4enYKaDExTyt3SlRCUGozdUN6RG00OHZFWjhsNVNYTU80d2QvUXF3c3JlakZFUlBEL0hkZnYxbUdDTVc3YWMwdWc4dApyRHpxR2UrbCtwOE5NanAvRXFCRFkydmQ4aExhVkxtUytYakFxbFlWTlJrc2g5YVR6U1lMMTkvY1RyQkRtcVEyCnk4azIzek5sMmxXNnEvQnRRT3BXR1ZzM0VXdkJIYi9RbmYzZjNTOStsQzRIMmpkRHk5eW43a3F5VFdxNFdDQm4KRTRxaFlKUm9rdWxZdHpNWk0xSWxrNFo2UlBrT1RSMU1KNGdkRnRqN2xLbXJrU3VPb0pZbXFoSklzUUo4NTRsQQpiSnliZ1U3enl6V0F3dTN1YXNsa1lLVUVBUWYyamE1SHlsM0lCcU96cHFZMzFTcEt6Ymw4Tlh2ZVp5YlJNa2x3CmZlNGlETEkyNVQ5a3U5Q1ZldERZaWZDYmRHZXVIZFR3WkJCZW1XNE5FNTdMN2lFVjgreno4bnhuZzhPTVgvLzQKcFhudFdxbVFiRUFuQkx2MlRvVGdkMUgyellSdGh5RExjM1YxMTkvK0ZuVFcxN0xLNmJLelRDZ0VuQ0hRRWNBdAowaERRTExGNzk5KzJsWlR4eGZCRW9kdUFaYXg2SWpnQU1DaTZlMVpmS1BKU2tkdmIybTNCd2ZQOGJuaUc3K0FFCkp2MVdPRW1uQkpjMXBWUUN0dGJKVW9kYmkwN1ZmZW41SlJVcUF2U00zT2JXUU96U0FHenNHbnBJaWd3RnBXNm0KOUY3dVlWVUNBd0VBQWFPQm96Q0JvREFkQmdOVkhRNEVGZ1FVc3NaN3BEVzdISlZrSEFtZ1FmL0YzRW1HRlZvdwpId1lEVlIwakJCZ3dGb0FVbjEzNS9nM1k4MXJRTXhvbDc0RXBUNzR4cUZzd0VnWURWUjBUQVFIL0JBZ3dCZ0VCCi93SUJBREFPQmdOVkhROEJBZjhFQkFNQ0FRUXdPZ1lEVlIwZkJETXdNVEF2b0MyZ0s0WXBhSFIwY0hNNkx5OXIKWkhOcGJuUm1MbUZ0WkM1amIyMHZkbU5sYXk5Mk1TOUhaVzV2WVM5amNtd3dSZ1lKS29aSWh2Y05BUUVLTURtZwpEekFOQmdsZ2hrZ0JaUU1FQWdJRkFLRWNNQm9HQ1NxR1NJYjNEUUVCQ0RBTkJnbGdoa2dCWlFNRUFnSUZBS0lECkFnRXdvd01DQVFFRGdnSUJBSWd1M1YydFFKT28wLzZHdk5td0xYYkxEcnNMS1hxSFVxZEd5T1pVcFBITTN1alQKYWV4MUcrOGJFZ0Jzd3dCYSt3TnZsMVNRcVJxeTJ4MlF3UCtpLy9CY1dyM2xNclV4Y2k0RzcvUDhoWkJWODIxbgpyQVVadGJ2ZnFsYTVNclJIOUFLSlhXVy9wbXRkMTBjenFDSGt6ZExRTlpOanQyZG5aSE1RQU10R3MxQXR5blJFCkhOd0VCaUgyS0F0N2dVYy9zS1duU0NpcHp0S0U3NnB1Ti9YWGJTeCtXcytWUGlGdzZDQkFlSTlkcW5FaVExdHAKRWdxdFdFdGNLbTdHZ2IxWEg2b1diSVNvb3d2YzAwL0FEV2ZOb20weGw2djJDNlJJV1lnVW9aMmY3UEN5VjNEdApidS9mUWZ5eVp2bXRWTEE0Z0IyRWhjNk9tankyMVk1NVdZOUl3ZUhsS0VOTVBFVVZ0UnFPdlJWSTBtbDlXYmFsCmYwNDlqb0N1MmozM1hQcXdwM0lyemV2bVBCREdwUjJTdGRtM0s2NmEvZy9CU1k3V2M5L1ZleWtQM1JYbHhZMVQKTU1KOEYxbHBnNlRtdStjK3ZvdzdjbGl5cU9vYXlBblI3MVU4K3JXckwzSFJIaGVTVlg4R1BZT2FETkJUdDgzMQpaMDI3dkRXdjM4MTF2TW94WXhodVRSYW9rdk5XQ1N6bUoyRVdyUFlIY0hPdGtqU0ZLTjdvdDBSYzcwZklSWkVZCmMycmIzeXdMU2ljRXEzSlFDbm56NmlDWjF0TWZwbHpjckoyTG5XMkYxQzh5UlYrb2t5bHlPUmxzYXhPTEtZT1cKamFEVFNGYXExTkl3b2RIcDdYOWZPRzQ4dVJ1SldTOEdtaWZEOTY5c0M0VXQyRkpGb2tsY2VCVlVOQ0hSCi0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0KLS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUZQekNDQXZPZ0F3SUJBZ0lCQURCQkJna3Foa2lHOXcwQkFRb3dOS0FQTUEwR0NXQ0dTQUZsQXdRQ0FnVUEKb1J3d0dnWUpLb1pJaHZjTkFRRUlNQTBHQ1dDR1NBRmxBd1FDQWdVQW9nTUNBVEF3ZXpFVU1CSUdBMVVFQ3d3TApSVzVuYVc1bFpYSnBibWN4Q3pBSkJnTlZCQVlUQWxWVE1SUXdFZ1lEVlFRSERBdFRZVzUwWVNCRGJHRnlZVEVMCk1Ba0dBMVVFQ0F3Q1EwRXhIekFkQmdOVkJBb01Ga0ZrZG1GdVkyVmtJRTFwWTNKdklFUmxkbWxqWlhNeEVqQVEKQmdOVkJBTU1DVk5GVmkxSFpXNXZZVEFlRncweU5UQTBNakF4T0RNeE16WmFGdzB6TWpBME1qQXhPRE14TXpaYQpNSG94RkRBU0JnTlZCQXNNQzBWdVoybHVaV1Z5YVc1bk1Rc3dDUVlEVlFRR0V3SlZVekVVTUJJR0ExVUVCd3dMClUyRnVkR0VnUTJ4aGNtRXhDekFKQmdOVkJBZ01Ba05CTVI4d0hRWURWUVFLREJaQlpIWmhibU5sWkNCTmFXTnkKYnlCRVpYWnBZMlZ6TVJFd0R3WURWUVFEREFoVFJWWXRWa05GU3pCMk1CQUdCeXFHU000OUFnRUdCU3VCQkFBaQpBMklBQk10VnFTcktXb3p5a0xCMUlEOEh2am5QVnZJa0RYVTBkamdHQ1JhZEFjTjY5NFJTTHd6Mnd2alhTTzNkClduRStsZFp0WWhUbnQ0aWZLbmgweFlGZUczdVJPZTJQK1dHQmk4SkExUktpQmRaeUJOd3VNQkgzcjFMUU5xcU8KaDZRZE9hT0NBUk13Z2dFUE1CQUdDU3NHQVFRQm5IZ0JBUVFEQWdFQU1CUUdDU3NHQVFRQm5IZ0JBZ1FIRmdWSApaVzV2WVRBUkJnb3JCZ0VFQVp4NEFRTUJCQU1DQVFvd0VRWUtLd1lCQkFHY2VBRURBZ1FEQWdFQU1CRUdDaXNHCkFRUUJuSGdCQXdRRUF3SUJBREFSQmdvckJnRUVBWng0QVFNRkJBTUNBUUF3RVFZS0t3WUJCQUdjZUFFREJnUUQKQWdFQU1CRUdDaXNHQVFRQm5IZ0JBd2NFQXdJQkFEQVJCZ29yQmdFRUFaeDRBUU1EQkFNQ0FSY3dFUVlLS3dZQgpCQUdjZUFFRENBUURBZ0ZVTUUwR0NTc0dBUVFCbkhnQkJBUkFleFdFeVV4NlFtRmtzdHNSbUpBOXNHaGJmMS9hCnZmUXRUYW1Cc041U0hSMWRYWXFSa3l1N3diRS9YVnl1UmFjd1JsZlpxZEFjVU1RMVp3OEZZcVdYQ3pCQkJna3EKaGtpRzl3MEJBUW93TktBUE1BMEdDV0NHU0FGbEF3UUNBZ1VBb1J3d0dnWUpLb1pJaHZjTkFRRUlNQTBHQ1dDRwpTQUZsQXdRQ0FnVUFvZ01DQVRBRGdnSUJBSGU2S0Q4R3psMVhvWHpMOG04eDNEZWtJVzhvbmdrdHFyWHQyQ0hoCkJSRFlYd2ZLZnhEN2d6WUdvRmFJTUJZaWZhTi94ZjRFK0NVZlY1bzRLTTZlQTBaeXN2MkRIaW5wVFp6ajdXdm8Kd0gra1pvc1VjdGVuNWFtRE0zMWMyY013akIvVjZGc1pib0VPV29Cd3k1Ty9JTWRlMU1PbG5VcmhhMlFpWmVpYgpFYVRPV3h3US9QSUNjN0J4aC84UEpNeUdweXFVdUVJT0M1akdTNkY3UU5TM0xzMXRtMzduUE5KVzBOZ0I3c0dlClVqcWl6OTNnN3FZM3ZZNlg0SGJ5Q241V0pObVVESVlZVmxRMHBhNFVNRU82QWpMRWV1WGorQi9Gc3JLY1p2d0oKMy9pSjJodXJrSEdGUmZvMUpCZEljRWFPS216UHgrMmNJekIwQTl6L0kvb3NzUStvWkZTcTc4TGY4enNnckxrVwpaUENmNjNRekZhYmFVNjNhcnlWQWZYMWRETkVHL203S0o0MmUzOGNuTFpCd05pUEswajJvd05BWTI2TkxXMUcyCmNTSTAyZkczVzVmYitaczhGQXg3Q0xaM1hvRSszMWhVWWc5dzNDaVpQRVFyUzkwL3B4eHhjbk9ZbENETE16SDAKRkdFV0tFbnJ6YjgyUm1sTlBZMXVtZ3E1Y3ZYV1NYNmdtY1JPWUJWMVB6L2N0aXpUa1VFQ1JhOGw2MVN0YVJmcApUeTZvRkw1YVR4QVYzUkxHRWI0dnl6dEZsUTQ0MVVaak5PU255L0xyZ2wva2dPQkw4R0NadTJoY3Niell4bGg2CmpGVEVCSUkvVWFza3BEc0dtdzl2L1VjUHFlUzNUaThBSnRac3dCS001WGV6UzRPMllvVllGSWhZWDJ4N3Zta1kKM0dUcwotLS0tLUVORCBDRVJUSUZJQ0FURS0tLS0tCg","outblob":"AwAAAAAAAAAAAAMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEAAAAKAAAAAAAXVCUAAAAAAAAAAAAAAAAAAABNSURCTkgyOGlpb2lzalB5eHh4eHh4eHh4eHh4eHh4eE1JREJOSDI4aWlvaXNqUHl4eHh4eHh4eHh4eHh4eHh4dpnmrBLM39HfrHDmSc4fBGyyr7sANDj0zd3-LMvhgvpf--jc25MEVDJOEMUseImAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACDf-blwwCyREa0gOZ4W0lHS-p1j5gGX9mE_WzvPgBoD___________________________________________CgAAAAAAF1QZEQEAAAAAAAAAAAAAAAAAAAAAAAAAAAB7FYTJTHpCYWSy2xGYkD2waFt_X9q99C1NqYGw3lIdHV1dipGTK7vBsT9dXK5FpzBGV9mp0BxQxDVnDwVipZcLCgAAAAAAF1QoNwEAKDcBAAoAAAAAABdUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAujZ3XnSPXeQA7RG0g7RhidcduhmZUzWrzN7ubpDhctTV8hfWvviK6uw3HVEo91kaAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADfG0-sEgeg7o4hxSjkSaqc4H8i9irEs7abYAsdfYisT07iAzoV-n0hkDjFxTLK8EAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA","provider":"sev_guest\n"} diff --git a/scheme/sevsnp/test/ta-endorsement-bad.json b/scheme/sevsnp/test/ta-endorsement-bad.json new file mode 100644 index 00000000..16f685bb --- /dev/null +++ b/scheme/sevsnp/test/ta-endorsement-bad.json @@ -0,0 +1,19 @@ +{ + "scheme": "SEVSNP", + "type": "trust anchor", + "subType": "", + "attributes": { + "environment": { + "class": { + "vendor": "AMD", + "model": "Milan" + } + }, + "verification-keys": [ + { + "type": "pkix-base64-cert", + "value":"-----BEGIN CERTIFICATE-----\nMIIFQzCCAvegAwIBAgIBADBBBgkqhkiG9w0BAQowNKAPMA0GCWCGSAFlAwQCAgUA\noRwwGgYJKoZIhvcNAQEIMA0GCWCGSAFlAwQCAgUAogMCATAwezEUMBIGA1UECwwL\nRW5naW5lZXJpbmcxCzAJBgNVBAYTAlVTMRQwEgYDVQQHDAtTYW50YSBDbGFyYTEL\nMAkGA1UECAwCQ0ExHzAdBgNVBAoMFkFkdmFuY2VkIE1pY3JvIERldmljZXMxEjAQ\nBgNVBAMMCVNFVi1NaWxhbjAeFw0yNTAxMjcyMzE3MDRaFw0zMjAxMjcyMzE3MDRa\nMHoxFDASBgNVBAsMC0VuZ2luZWVyaW5nMQswCQYDVQQGEwJVUzEUMBIGA1UEBwwL\nU2FudGEgQ2xhcmExCzAJBgNVBAgMAkNBMR8wHQYDVQQKDBZBZHZhbmNlZCBNaWNy\nbyBEZXZpY2VzMREwDwYDVQQDDAhTRVYtVkNFSzB2MBAGByqGSM49AgEGBSuBBAAi\nA2IABCoUIuBoilHXQKx+9uMHC3j+JjMdzzlVQCshIlhcCQAcpkZb2M9ixLc9ezJg\nrH2u2auDkN4dCDVJXMtrc+4kmK5aZb8GP0EIqbAPv7tFx3ebGdbJWF+d/EH3Yaoi\nlnlFaaOCARcwggETMBAGCSsGAQQBnHgBAQQDAgEAMBcGCSsGAQQBnHgBAgQKFghN\naWxhbi1CMDARBgorBgEEAZx4AQMBBAMCAQQwEQYKKwYBBAGceAEDAgQDAgEAMBEG\nCisGAQQBnHgBAwQEAwIBADARBgorBgEEAZx4AQMFBAMCAQAwEQYKKwYBBAGceAED\nBgQDAgEAMBEGCisGAQQBnHgBAwcEAwIBADARBgorBgEEAZx4AQMDBAMCARgwEgYK\nKwYBBAGceAEDCAQEAgIA2zBNBgkrBgEEAZx4AQQEQMKmUotzZOB+n1xlOrOqDb1z\nhPmoDf3lTMZD3buJ2JNkJf+KMlaMpu13ECDcOcM8z/s7Q8rAxQGgCTytYBLf0+0w\nQQYJKoZIhvcNAQEKMDSgDzANBglghkgBZQMEAgIFAKEcMBoGCSqGSIb3DQEBCDAN\nBglghkgBZQMEAgIFAKIDAgEwA4ICAQAlLqDsAbNdEYToxSGiuS4hoa66OvHXHla/\nhoeEtwrf91IPPvSdZJwdb6lMfVx7Ez9PXndnRIML0t/N+x5dKlSpjPUea8ETaFvr\nBfCANXO9xAuTZZJQ3KdyjR0p8781CM9Z/YoT0/wiWCqg96xj3WuvC03pJRuQHOhz\n7/KvPOs6YXRU2h/BVd48NkKaQcgv3t4nviTBg6pIYe8omLzCe98MO3OU9bf3iDP3\nYtcLMmojQcV53r+DFGlzxfP5U7n8Qz87GbMhKoVmo+HaACKEDs5gjoMtE85bvuCV\nZw3hNxsqmcZQoFbhE6oZPF9d3/5iz0nTz1WR8QGDsRVA7j04sjYtYnTxqVuTQGbW\n19KB9H52OlT/LWkVy4WBsfeP1PZi/LaneI2bO8muUE0F3fAw85FigzXrJsYYz7gX\nCcsdi5ZZVtKarbpVvKJNgAkJN100WQB4ERQxHu0i5iHsuZKvcGZNBIRneWqcXbtW\nLNa3ME6jV+/Bc8vQFgcGago2bqEmoJo+g81AHD1rqbIya8gVvVC+J0ZbYXtxSZJS\nKyKOEUcKXMcdoow0AsdIF2KVs8/xpiVIgh8MF6Vk1pPxhHx4mIlhgg3t46xKzKKJ\npuyP5wLw1Ji8Ia3VaJvPyP1XFlbzwL71iNEkUI2jkfB6xozmYZsBOVKsJe2PVeNu\nMd3Wy3hVWA==\n-----END CERTIFICATE-----" + } + ] + } +} \ No newline at end of file diff --git a/scheme/sevsnp/test/ta-endorsement.json b/scheme/sevsnp/test/ta-endorsement.json new file mode 100644 index 00000000..53b7426d --- /dev/null +++ b/scheme/sevsnp/test/ta-endorsement.json @@ -0,0 +1,19 @@ +{ + "scheme": "SEVSNP", + "type": "trust anchor", + "subType": "", + "attributes": { + "environment": { + "class": { + "vendor": "AMD", + "model": "Genoa" + } + }, + "verification-keys": [ + { + "type": "pkix-base64-cert", + "value": "-----BEGIN CERTIFICATE-----\nMIIGYzCCBBKgAwIBAgIDAgAAMEYGCSqGSIb3DQEBCjA5oA8wDQYJYIZIAWUDBAIC\nBQChHDAaBgkqhkiG9w0BAQgwDQYJYIZIAWUDBAICBQCiAwIBMKMDAgEBMHsxFDAS\nBgNVBAsMC0VuZ2luZWVyaW5nMQswCQYDVQQGEwJVUzEUMBIGA1UEBwwLU2FudGEg\nQ2xhcmExCzAJBgNVBAgMAkNBMR8wHQYDVQQKDBZBZHZhbmNlZCBNaWNybyBEZXZp\nY2VzMRIwEAYDVQQDDAlBUkstR2Vub2EwHhcNMjIwMTI2MTUzNDM3WhcNNDcwMTI2\nMTUzNDM3WjB7MRQwEgYDVQQLDAtFbmdpbmVlcmluZzELMAkGA1UEBhMCVVMxFDAS\nBgNVBAcMC1NhbnRhIENsYXJhMQswCQYDVQQIDAJDQTEfMB0GA1UECgwWQWR2YW5j\nZWQgTWljcm8gRGV2aWNlczESMBAGA1UEAwwJQVJLLUdlbm9hMIICIjANBgkqhkiG\n9w0BAQEFAAOCAg8AMIICCgKCAgEA3Cd95S/uFOuRIskW9vz9VDBF69NDQF79oRhL\n/L2PVQGhK3YdfEBgpF/JiwWFBsT/fXDhzA01p3LkcT/7LdjcRfKXjHl+0Qq/M4dZ\nkh6QDoUeKzNBLDcBKDDGWo3v35NyrxbA1DnkYwUKU5AAk4P94tKXLp80oxt84ahy\nHoLmc/LqsGsp+oq1Bz4PPsYLwTG4iMKVaaT90/oZ4I8oibSru92vJhlqWO27d/Rx\nc3iUMyhNeGToOvgx/iUo4gGpG61NDpkEUvIzuKcaMx8IdTpWg2DF6SwF0IgVMffn\nvtJmA68BwJNWo1E4PLJdaPfBifcJpuBFwNVQIPQEVX3aP89HJSp8YbY9lySS6PlV\nEqTBBtaQmi4ATGmMR+n2K/e+JAhU2Gj7jIpJhOkdH9firQDnmlA2SFfJ/Cc0mGNz\nW9RmIhyOUnNFoclmkRhl3/AQU5Ys9Qsan1jT/EiyT+pCpmnA+y9edvhDCbOG8F2o\nxHGRdTBkylungrkXJGYiwGrR8kaiqv7NN8QhOBMqYjcbrkEr0f8QMKklIS5ruOfq\nlLMCBw8JLB3LkjpWgtD7OpxkzSsohN47Uom86RY6lp72g8eXHP1qYrnvhzaG1S70\nvw6OkbaaC9EjiH/uHgAJQGxon7u0Q7xgoREWA/e7JcBQwLg80Hq/sbRuqesxz7wB\nWSY254cCAwEAAaN+MHwwDgYDVR0PAQH/BAQDAgEGMB0GA1UdDgQWBBSfXfn+Ddjz\nWtAzGiXvgSlPvjGoWzAPBgNVHRMBAf8EBTADAQH/MDoGA1UdHwQzMDEwL6AtoCuG\nKWh0dHBzOi8va2RzaW50Zi5hbWQuY29tL3ZjZWsvdjEvR2Vub2EvY3JsMEYGCSqG\nSIb3DQEBCjA5oA8wDQYJYIZIAWUDBAICBQChHDAaBgkqhkiG9w0BAQgwDQYJYIZI\nAWUDBAICBQCiAwIBMKMDAgEBA4ICAQAdIlPBC7DQmvH7kjlOznFx3i21SzOPDs5L\n7SgFjMC9rR07292GQCA7Z7Ulq97JQaWeD2ofGGse5swj4OQfKfVv/zaJUFjvosZO\nnfZ63epu8MjWgBSXJg5QE/Al0zRsZsp53DBTdA+Uv/s33fexdenT1mpKYzhIg/cK\ntz4oMxq8JKWJ8Po1CXLzKcfrTphjlbkh8AVKMXeBd2SpM33B1YP4g1BOdk013kqb\n7bRHZ1iB2JHG5cMKKbwRCSAAGHLTzASgDcXr9Fp7Z3liDhGu/ci1opGmkp12QNiJ\nuBbkTU+xDZHm5X8Jm99BX7NEpzlOwIVR8ClgBDyuBkBC2ljtr3ZSaUIYj2xuyWN9\n5KFY49nWxcz90CFa3Hzmy4zMQmBe9dVyls5eL5p9bkXcgRMDTbgmVZiAf4afe8DL\ndmQcYcMFQbHhgVzMiyZHGJgcCrQmA7MkTwEIds1wx/HzMcwU4qqNBAoZV7oeIIPx\ndqFXfPqHqiRlEbRDfX1TG5NFVaeByX0GyH6jzYVuezETzruaky6fp2bl2bczxPE8\nHdS38ijiJmm9vl50RGUeOAXjSuInGR4bsRufeGPB9peTa9BcBOeTWzstqTUB/F/q\naZCIZKr4X6TyfUuSDz/1JDAGl+lxdM0P9+lLaP9NahQjHCVf0zf1c1salVuGFk2w\n/wMz1R1BHg==\n-----END CERTIFICATE-----\n" + } + ] + } +} diff --git a/scheme/sevsnp/test/ta-prov.json b/scheme/sevsnp/test/ta-prov.json new file mode 100644 index 00000000..84d59d7b --- /dev/null +++ b/scheme/sevsnp/test/ta-prov.json @@ -0,0 +1,25 @@ +{ + "lang": "en-GB", + "tag-identity": { + "id": "a331c36f-09df-4d2a-9c04-8a64c0805c5d", + "version": 0 + }, + "triples": { + "attester-verification-keys": [ + { + "environment": { + "class": { + "vendor": "AMD", + "model": "Milan" + } + }, + "verification-keys": [ + { + "type": "pkix-base64-cert", + "value": "-----BEGIN CERTIFICATE-----\nMIIGYzCCBBKgAwIBAgIDAQAAMEYGCSqGSIb3DQEBCjA5oA8wDQYJYIZIAWUDBAIC\nBQChHDAaBgkqhkiG9w0BAQgwDQYJYIZIAWUDBAICBQCiAwIBMKMDAgEBMHsxFDAS\nBgNVBAsMC0VuZ2luZWVyaW5nMQswCQYDVQQGEwJVUzEUMBIGA1UEBwwLU2FudGEg\nQ2xhcmExCzAJBgNVBAgMAkNBMR8wHQYDVQQKDBZBZHZhbmNlZCBNaWNybyBEZXZp\nY2VzMRIwEAYDVQQDDAlBUkstTWlsYW4wHhcNMjAxMDIyMTcyMzA1WhcNNDUxMDIy\nMTcyMzA1WjB7MRQwEgYDVQQLDAtFbmdpbmVlcmluZzELMAkGA1UEBhMCVVMxFDAS\nBgNVBAcMC1NhbnRhIENsYXJhMQswCQYDVQQIDAJDQTEfMB0GA1UECgwWQWR2YW5j\nZWQgTWljcm8gRGV2aWNlczESMBAGA1UEAwwJQVJLLU1pbGFuMIICIjANBgkqhkiG\n9w0BAQEFAAOCAg8AMIICCgKCAgEA0Ld52RJOdeiJlqK2JdsVmD7FktuotWwX1fNg\nW41XY9Xz1HEhSUmhLz9Cu9DHRlvgJSNxbeYYsnJfvyjx1MfU0V5tkKiU1EesNFta\n1kTA0szNisdYc9isqk7mXT5+KfGRbfc4V/9zRIcE8jlHN61S1ju8X93+6dxDUrG2\nSzxqJ4BhqyYmUDruPXJSX4vUc01P7j98MpqOS95rORdGHeI52Naz5m2B+O+vjsC0\n60d37jY9LFeuOP4Meri8qgfi2S5kKqg/aF6aPtuAZQVR7u3KFYXP59XmJgtcog05\ngmI0T/OitLhuzVvpZcLph0odh/1IPXqx3+MnjD97A7fXpqGd/y8KxX7jksTEzAOg\nbKAeam3lm+3yKIcTYMlsRMXPcjNbIvmsBykD//xSniusuHBkgnlENEWx1UcbQQrs\n+gVDkuVPhsnzIRNgYvM48Y+7LGiJYnrmE8xcrexekBxrva2V9TJQqnN3Q53kt5vi\nQi3+gCfmkwC0F0tirIZbLkXPrPwzZ0M9eNxhIySb2npJfgnqz55I0u33wh4r0ZNQ\neTGfw03MBUtyuzGesGkcw+loqMaq1qR4tjGbPYxCvpCq7+OgpCCoMNit2uLo9M18\nfHz10lOMT8nWAUvRZFzteXCm+7PHdYPlmQwUw3LvenJ/ILXoQPHfbkH0CyPfhl1j\nWhJFZasCAwEAAaN+MHwwDgYDVR0PAQH/BAQDAgEGMB0GA1UdDgQWBBSFrBrRQ/fI\nrFXUxR1BSKvVeErUUzAPBgNVHRMBAf8EBTADAQH/MDoGA1UdHwQzMDEwL6AtoCuG\nKWh0dHBzOi8va2RzaW50Zi5hbWQuY29tL3ZjZWsvdjEvTWlsYW4vY3JsMEYGCSqG\nSIb3DQEBCjA5oA8wDQYJYIZIAWUDBAICBQChHDAaBgkqhkiG9w0BAQgwDQYJYIZI\nAWUDBAICBQCiAwIBMKMDAgEBA4ICAQC6m0kDp6zv4Ojfgy+zleehsx6ol0ocgVel\nETobpx+EuCsqVFRPK1jZ1sp/lyd9+0fQ0r66n7kagRk4Ca39g66WGTJMeJdqYriw\nSTjjDCKVPSesWXYPVAyDhmP5n2v+BYipZWhpvqpaiO+EGK5IBP+578QeW/sSokrK\ndHaLAxG2LhZxj9aF73fqC7OAJZ5aPonw4RE299FVarh1Tx2eT3wSgkDgutCTB1Yq\nzT5DuwvAe+co2CIVIzMDamYuSFjPN0BCgojl7V+bTou7dMsqIu/TW/rPCX9/EUcp\nKGKqPQ3P+N9r1hjEFY1plBg93t53OOo49GNI+V1zvXPLI6xIFVsh+mto2RtgEX/e\npmMKTNN6psW88qg7c1hTWtN6MbRuQ0vm+O+/2tKBF2h8THb94OvvHHoFDpbCELlq\nHnIYhxy0YKXGyaW1NjfULxrrmxVW4wcn5E8GddmvNa6yYm8scJagEi13mhGu4Jqh\n3QU3sf8iUSUr09xQDwHtOQUVIqx4maBZPBtSMf+qUDtjXSSq8lfWcd8bLr9mdsUn\nJZJ0+tuPMKmBnSH860llKk+VpVQsgqbzDIvOLvD6W1Umq25boxCYJ+TuBoa4s+HH\nCViAvgT9kf/rBq1d+ivj6skkHxuzcxbk1xv6ZGxrteJxVH7KlX7YRdZ6eARKwLe4\nAFZEAwoKCQ==\n-----END CERTIFICATE-----\n" + } + ] + } + ] + } +} diff --git a/scheme/sevsnp/test_vectors.go b/scheme/sevsnp/test_vectors.go new file mode 100644 index 00000000..bc34edd1 --- /dev/null +++ b/scheme/sevsnp/test_vectors.go @@ -0,0 +1,10 @@ +// Copyright 2025 Contributors to the Veraison project. +// SPDX-License-Identifier: Apache-2.0 +package sevsnp + +import _ "embed" + +var ( + //go:embed test/corim/unsignedCorimSevSnp.cbor + unsignedCorimSevSnp []byte +)