mirror of
https://github.com/edgelesssys/constellation.git
synced 2024-12-25 07:29:38 -05:00
attestation: use go-sev-guest
library (#2269)
* wip: switch to attestation * add extra comments Signed-off-by: Moritz Sanft <58110325+msanft@users.noreply.github.com> * MAA checks Signed-off-by: Moritz Sanft <58110325+msanft@users.noreply.github.com> * use provided functions to parse report / cert chain Signed-off-by: Moritz Sanft <58110325+msanft@users.noreply.github.com> * replace `CommitedTCB` check with `LaunchTCB` check Signed-off-by: Moritz Sanft <58110325+msanft@users.noreply.github.com> * remove debug check Signed-off-by: Moritz Sanft <58110325+msanft@users.noreply.github.com> * remove `LaunchTCB` == `CommitedTCB` check Signed-off-by: Moritz Sanft <58110325+msanft@users.noreply.github.com> * custom IdKeyDigests check Signed-off-by: Moritz Sanft <58110325+msanft@users.noreply.github.com> * basic test of report parsing from instance info Signed-off-by: Moritz Sanft <58110325+msanft@users.noreply.github.com> * retrieve VCEK from AMD KDS Signed-off-by: Moritz Sanft <58110325+msanft@users.noreply.github.com> * remove VCEK from `azureInstanceInfo` Signed-off-by: Moritz Sanft <58110325+msanft@users.noreply.github.com> * use `go-sev-guest` TCB version type Signed-off-by: Moritz Sanft <58110325+msanft@users.noreply.github.com> * fix validation parsing test Signed-off-by: Moritz Sanft <58110325+msanft@users.noreply.github.com> * fix error message * fix comment Signed-off-by: Moritz Sanft <58110325+msanft@users.noreply.github.com> * remove certificate chain from `instanceInfo` Signed-off-by: Moritz Sanft <58110325+msanft@users.noreply.github.com> * add test for idkeydigest check Signed-off-by: Moritz Sanft <58110325+msanft@users.noreply.github.com> * update buildfiles Signed-off-by: Moritz Sanft <58110325+msanft@users.noreply.github.com> * wip: update tests Signed-off-by: Moritz Sanft <58110325+msanft@users.noreply.github.com> * update buildfiles Signed-off-by: Moritz Sanft <58110325+msanft@users.noreply.github.com> * [remove] debug prints Signed-off-by: Moritz Sanft <58110325+msanft@users.noreply.github.com> * wip: fix tests Signed-off-by: Moritz Sanft <58110325+msanft@users.noreply.github.com> * wip: fix tests Signed-off-by: Moritz Sanft <58110325+msanft@users.noreply.github.com> * fix tests, do some clean-up Signed-off-by: Moritz Sanft <58110325+msanft@users.noreply.github.com> * add test case for fetching error Signed-off-by: Moritz Sanft <58110325+msanft@users.noreply.github.com> * Update internal/attestation/azure/snp/validator.go Co-authored-by: Daniel Weiße <66256922+daniel-weisse@users.noreply.github.com> * correct `hack` dependency Signed-off-by: Moritz Sanft <58110325+msanft@users.noreply.github.com> * fix id key check Signed-off-by: Moritz Sanft <58110325+msanft@users.noreply.github.com> * [remove] comment out wip unit tests Signed-off-by: Moritz Sanft <58110325+msanft@users.noreply.github.com> * add missing newline Signed-off-by: Moritz Sanft <58110325+msanft@users.noreply.github.com> * switch to released version of `go-sev-guest` Signed-off-by: Moritz Sanft <58110325+msanft@users.noreply.github.com> * add constructor test Signed-off-by: Moritz Sanft <58110325+msanft@users.noreply.github.com> * add VMPL check Signed-off-by: Moritz Sanft <58110325+msanft@users.noreply.github.com> * add test assertions Signed-off-by: Moritz Sanft <58110325+msanft@users.noreply.github.com> * update buildfiles Signed-off-by: Moritz Sanft <58110325+msanft@users.noreply.github.com> * switch to pseudoversion Signed-off-by: Moritz Sanft <58110325+msanft@users.noreply.github.com> * use fork with windows fix Signed-off-by: Moritz Sanft <58110325+msanft@users.noreply.github.com> * fix linter checks Signed-off-by: Moritz Sanft <58110325+msanft@users.noreply.github.com> * use data from THIM Signed-off-by: Moritz Sanft <58110325+msanft@users.noreply.github.com> * update embeds Signed-off-by: Moritz Sanft <58110325+msanft@users.noreply.github.com> * verify against ARK in config Signed-off-by: Moritz Sanft <58110325+msanft@users.noreply.github.com> * invalid ASK Signed-off-by: Moritz Sanft <58110325+msanft@users.noreply.github.com> * Update internal/attestation/azure/snp/validator.go Co-authored-by: Thomas Tendyck <51411342+thomasten@users.noreply.github.com> * Update internal/attestation/azure/snp/validator.go Co-authored-by: Thomas Tendyck <51411342+thomasten@users.noreply.github.com> * Update internal/attestation/azure/snp/validator.go Co-authored-by: 3u13r <lc@edgeless.systems> * Update internal/attestation/azure/snp/validator.go Co-authored-by: 3u13r <lc@edgeless.systems> * nits Signed-off-by: Moritz Sanft <58110325+msanft@users.noreply.github.com> * remove unnecessary checks Signed-off-by: Moritz Sanft <58110325+msanft@users.noreply.github.com> * refactoring Signed-off-by: Moritz Sanft <58110325+msanft@users.noreply.github.com> * Update internal/attestation/azure/snp/validator.go Co-authored-by: Thomas Tendyck <51411342+thomasten@users.noreply.github.com> * Update internal/attestation/azure/snp/validator.go Co-authored-by: Thomas Tendyck <51411342+thomasten@users.noreply.github.com> * Update internal/attestation/azure/snp/validator.go Co-authored-by: Thomas Tendyck <51411342+thomasten@users.noreply.github.com> * use upstream library with pseudoversion Signed-off-by: Moritz Sanft <58110325+msanft@users.noreply.github.com> * Update internal/attestation/azure/snp/validator.go Co-authored-by: Paul Meyer <49727155+katexochen@users.noreply.github.com> * Update internal/attestation/azure/snp/validator.go Co-authored-by: Paul Meyer <49727155+katexochen@users.noreply.github.com> * Update internal/attestation/azure/snp/validator.go Co-authored-by: Paul Meyer <49727155+katexochen@users.noreply.github.com> * simplify control flow Signed-off-by: Moritz Sanft <58110325+msanft@users.noreply.github.com> * fix return error Signed-off-by: Moritz Sanft <58110325+msanft@users.noreply.github.com> * fix VCEK test Signed-off-by: Moritz Sanft <58110325+msanft@users.noreply.github.com> * tidy Signed-off-by: Moritz Sanft <58110325+msanft@users.noreply.github.com> * revert unintentional changes Signed-off-by: Moritz Sanft <58110325+msanft@users.noreply.github.com> * use new upstream release Signed-off-by: Moritz Sanft <58110325+msanft@users.noreply.github.com> * fix removed AuthorKeyEn field Signed-off-by: Moritz Sanft <58110325+msanft@users.noreply.github.com> * fix verification report printing Signed-off-by: Moritz Sanft <58110325+msanft@users.noreply.github.com> --------- Signed-off-by: Moritz Sanft <58110325+msanft@users.noreply.github.com> Co-authored-by: Daniel Weiße <66256922+daniel-weisse@users.noreply.github.com> Co-authored-by: Thomas Tendyck <51411342+thomasten@users.noreply.github.com> Co-authored-by: 3u13r <lc@edgeless.systems> Co-authored-by: Paul Meyer <49727155+katexochen@users.noreply.github.com>
This commit is contained in:
parent
8f549f0622
commit
3ed001fa8a
@ -2456,8 +2456,8 @@ def go_dependencies():
|
||||
build_file_generation = "on",
|
||||
build_file_proto_mode = "disable_global",
|
||||
importpath = "github.com/google/go-sev-guest",
|
||||
sum = "h1:NajHkAaLqN9/aW7bCFSUplUMtDgk2+HcN7jC2btFtk0=",
|
||||
version = "v0.6.1",
|
||||
sum = "h1:IIZIqdcMJXgTm1nMvId442OUpYebbWDWa9bi9/lUUwc=",
|
||||
version = "v0.8.0",
|
||||
)
|
||||
go_repository(
|
||||
name = "com_github_google_go_tpm",
|
||||
@ -2595,8 +2595,8 @@ def go_dependencies():
|
||||
build_file_generation = "on",
|
||||
build_file_proto_mode = "disable_global",
|
||||
importpath = "github.com/google/uuid",
|
||||
sum = "h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I=",
|
||||
version = "v1.3.0",
|
||||
sum = "h1:KjJaJ9iWZ3jOFZIf1Lqf4laDRCasjl0BCmnEGxkdLb4=",
|
||||
version = "v1.3.1",
|
||||
)
|
||||
go_repository(
|
||||
name = "com_github_google_wire",
|
||||
@ -7324,8 +7324,8 @@ def go_dependencies():
|
||||
build_file_generation = "on",
|
||||
build_file_proto_mode = "disable_global",
|
||||
importpath = "golang.org/x/crypto",
|
||||
sum = "h1:tFM/ta59kqch6LlvYnPa0yx5a83cL2nHflFhYKvv9Yk=",
|
||||
version = "v0.12.0",
|
||||
sum = "h1:mvySKfSWJ+UKUii46M40LOvyWfN0s2U+46/jDd0e6Ck=",
|
||||
version = "v0.13.0",
|
||||
)
|
||||
go_repository(
|
||||
name = "org_golang_x_exp",
|
||||
@ -7397,24 +7397,24 @@ def go_dependencies():
|
||||
build_file_generation = "on",
|
||||
build_file_proto_mode = "disable_global",
|
||||
importpath = "golang.org/x/sys",
|
||||
sum = "h1:eG7RXZHdqOJ1i+0lgLgCpSXAp6M3LYlAo6osgSi0xOM=",
|
||||
version = "v0.11.0",
|
||||
sum = "h1:CM0HF96J0hcLAwsHPJZjfdNzs0gftsLfgKt57wWHJ0o=",
|
||||
version = "v0.12.0",
|
||||
)
|
||||
go_repository(
|
||||
name = "org_golang_x_term",
|
||||
build_file_generation = "on",
|
||||
build_file_proto_mode = "disable_global",
|
||||
importpath = "golang.org/x/term",
|
||||
sum = "h1:F9tnn/DA/Im8nCwm+fX+1/eBwi4qFjRT++MhtVC4ZX0=",
|
||||
version = "v0.11.0",
|
||||
sum = "h1:/ZfYdc3zq+q02Rv9vGqTeSItdzZTSNDmfTi0mBAuidU=",
|
||||
version = "v0.12.0",
|
||||
)
|
||||
go_repository(
|
||||
name = "org_golang_x_text",
|
||||
build_file_generation = "on",
|
||||
build_file_proto_mode = "disable_global",
|
||||
importpath = "golang.org/x/text",
|
||||
sum = "h1:k+n5B8goJNdU7hSvEtMUz3d1Q6D/XW4COJSJR6fN0mc=",
|
||||
version = "v0.12.0",
|
||||
sum = "h1:ablQoSUd0tRdKxZewP80B+BaqeKJuVhuRxj/dkrun3k=",
|
||||
version = "v0.13.0",
|
||||
)
|
||||
go_repository(
|
||||
name = "org_golang_x_time",
|
||||
|
@ -428,6 +428,11 @@ func (f *attestationDocFormatterImpl) parseSNPReport(b *strings.Builder, reportB
|
||||
return fmt.Errorf("parsing signature: %w", err)
|
||||
}
|
||||
|
||||
signerInfo, err := abi.ParseSignerInfo(report.SignerInfo)
|
||||
if err != nil {
|
||||
return fmt.Errorf("parsing signer info: %w", err)
|
||||
}
|
||||
|
||||
writeTCB := func(tcbVersion uint64) {
|
||||
tcb := kds.DecomposeTCBVersion(kds.TCBVersion(tcbVersion))
|
||||
writeIndentfln(b, 3, "Secure Processor bootloader SVN: %d", tcb.BlSpl)
|
||||
@ -459,7 +464,10 @@ func (f *attestationDocFormatterImpl) parseSNPReport(b *strings.Builder, reportB
|
||||
writeIndentfln(b, 2, "Platform Info:")
|
||||
writeIndentfln(b, 3, "Symmetric Multithreading enabled (SMT): %t", platformInfo.SMTEnabled)
|
||||
writeIndentfln(b, 3, "Transparent secure memory encryption (TSME): %t", platformInfo.TSMEEnabled)
|
||||
writeIndentfln(b, 2, "Author Key ID: %x", report.AuthorKeyEn)
|
||||
writeIndentfln(b, 2, "Signer Info:")
|
||||
writeIndentfln(b, 3, "Author Key Enabled: %t", signerInfo.AuthorKeyEn)
|
||||
writeIndentfln(b, 3, "Chip ID Masking: %t", signerInfo.MaskChipKey)
|
||||
writeIndentfln(b, 3, "Signing Type: %s", signerInfo.SigningKey)
|
||||
writeIndentfln(b, 2, "Report Data: %x", report.ReportData)
|
||||
writeIndentfln(b, 2, "Measurement: %x", report.Measurement)
|
||||
writeIndentfln(b, 2, "Host Data: %x", report.HostData)
|
||||
|
12
go.mod
12
go.mod
@ -77,10 +77,10 @@ require (
|
||||
github.com/go-playground/universal-translator v0.18.1
|
||||
github.com/go-playground/validator/v10 v10.14.1
|
||||
github.com/golang-jwt/jwt/v5 v5.0.0
|
||||
github.com/google/go-sev-guest v0.6.1
|
||||
github.com/google/go-sev-guest v0.8.0
|
||||
github.com/google/go-tpm v0.9.0
|
||||
github.com/google/go-tpm-tools v0.4.0
|
||||
github.com/google/uuid v1.3.0
|
||||
github.com/google/uuid v1.3.1
|
||||
github.com/googleapis/gax-go/v2 v2.12.0
|
||||
github.com/gophercloud/gophercloud v1.5.0
|
||||
github.com/gophercloud/utils v0.0.0-20230523080330-de873b9cf00d
|
||||
@ -109,9 +109,9 @@ require (
|
||||
github.com/theupdateframework/go-tuf v0.5.2
|
||||
go.uber.org/goleak v1.2.1
|
||||
go.uber.org/zap v1.24.0
|
||||
golang.org/x/crypto v0.12.0
|
||||
golang.org/x/crypto v0.13.0
|
||||
golang.org/x/mod v0.12.0
|
||||
golang.org/x/sys v0.11.0
|
||||
golang.org/x/sys v0.12.0
|
||||
golang.org/x/tools v0.10.0
|
||||
google.golang.org/api v0.130.0
|
||||
google.golang.org/grpc v1.56.2
|
||||
@ -321,8 +321,8 @@ require (
|
||||
golang.org/x/net v0.14.0 // indirect
|
||||
golang.org/x/oauth2 v0.9.0 // indirect
|
||||
golang.org/x/sync v0.3.0 // indirect
|
||||
golang.org/x/term v0.11.0 // indirect
|
||||
golang.org/x/text v0.12.0 // indirect
|
||||
golang.org/x/term v0.12.0 // indirect
|
||||
golang.org/x/text v0.13.0 // indirect
|
||||
golang.org/x/time v0.3.0 // indirect
|
||||
golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2 // indirect
|
||||
google.golang.org/appengine v1.6.7 // indirect
|
||||
|
23
go.sum
23
go.sum
@ -535,8 +535,8 @@ github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38=
|
||||
github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
|
||||
github.com/google/go-containerregistry v0.15.2 h1:MMkSh+tjSdnmJZO7ljvEqV1DjfekB6VUEAZgy3a+TQE=
|
||||
github.com/google/go-containerregistry v0.15.2/go.mod h1:wWK+LnOv4jXMM23IT/F1wdYftGWGr47Is8CG+pmHK1Q=
|
||||
github.com/google/go-sev-guest v0.6.1 h1:NajHkAaLqN9/aW7bCFSUplUMtDgk2+HcN7jC2btFtk0=
|
||||
github.com/google/go-sev-guest v0.6.1/go.mod h1:UEi9uwoPbLdKGl1QHaq1G8pfCbQ4QP0swWX4J0k6r+Q=
|
||||
github.com/google/go-sev-guest v0.8.0 h1:IIZIqdcMJXgTm1nMvId442OUpYebbWDWa9bi9/lUUwc=
|
||||
github.com/google/go-sev-guest v0.8.0/go.mod h1:hc1R4R6f8+NcJwITs0L90fYWTsBpd1Ix+Gur15sqHDs=
|
||||
github.com/google/go-tpm-tools v0.4.0 h1:bYRZAUvQEmn11WTKCkTLRCCv4aTlOBgBBeqCK0ABT2A=
|
||||
github.com/google/go-tpm-tools v0.4.0/go.mod h1:G7PFUk8KKQzdYYGv/cpV9LB9sPT7czAAomnceugzNKQ=
|
||||
github.com/google/go-tspi v0.3.0 h1:ADtq8RKfP+jrTyIWIZDIYcKOMecRqNJFOew2IT0Inus=
|
||||
@ -573,8 +573,9 @@ github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510/go.mod h1:pupxD2MaaD3
|
||||
github.com/google/uuid v1.0.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||
github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||
github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||
github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I=
|
||||
github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||
github.com/google/uuid v1.3.1 h1:KjJaJ9iWZ3jOFZIf1Lqf4laDRCasjl0BCmnEGxkdLb4=
|
||||
github.com/google/uuid v1.3.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||
github.com/googleapis/enterprise-certificate-proxy v0.2.5 h1:UR4rDjcgpgEnqpIEvkiqTYKBCKLNmlge2eVjoZfySzM=
|
||||
github.com/googleapis/enterprise-certificate-proxy v0.2.5/go.mod h1:RxW0N9901Cko1VOCW3SXCpWP+mlIEkk2tP7jnHy9a3w=
|
||||
github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg=
|
||||
@ -1112,8 +1113,8 @@ golang.org/x/crypto v0.0.0-20220829220503-c86fa9a7ed90/go.mod h1:IxCIyHEi3zRg3s0
|
||||
golang.org/x/crypto v0.3.0/go.mod h1:hebNnKkNXi2UzZN1eVRvBB7co0a+JxK6XbPiWVs/3J4=
|
||||
golang.org/x/crypto v0.5.0/go.mod h1:NK/OQwhpMQP3MwtdjgLlYHnH9ebylxKWv3e0fK+mkQU=
|
||||
golang.org/x/crypto v0.6.0/go.mod h1:OFC/31mSvZgRz0V1QTNCzfAI1aIRzbiufJtkMIlEp58=
|
||||
golang.org/x/crypto v0.12.0 h1:tFM/ta59kqch6LlvYnPa0yx5a83cL2nHflFhYKvv9Yk=
|
||||
golang.org/x/crypto v0.12.0/go.mod h1:NF0Gs7EO5K4qLn+Ylc+fih8BSTeIjAP05siRnAh98yw=
|
||||
golang.org/x/crypto v0.13.0 h1:mvySKfSWJ+UKUii46M40LOvyWfN0s2U+46/jDd0e6Ck=
|
||||
golang.org/x/crypto v0.13.0/go.mod h1:y6Z2r+Rw4iayiXXAIxJIDAJ1zMW4yaTpebo8fPOliYc=
|
||||
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
||||
golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
||||
golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8=
|
||||
@ -1313,8 +1314,8 @@ golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.4.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.11.0 h1:eG7RXZHdqOJ1i+0lgLgCpSXAp6M3LYlAo6osgSi0xOM=
|
||||
golang.org/x/sys v0.11.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.12.0 h1:CM0HF96J0hcLAwsHPJZjfdNzs0gftsLfgKt57wWHJ0o=
|
||||
golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
|
||||
golang.org/x/term v0.1.0/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
|
||||
@ -1322,8 +1323,8 @@ golang.org/x/term v0.2.0/go.mod h1:TVmDHMZPmdnySmBfhjOoOdhjzdE1h4u1VwSiw2l1Nuc=
|
||||
golang.org/x/term v0.4.0/go.mod h1:9P2UbLfCdcvo3p/nzKvsmas4TnlujnuoV9hGgYzW1lQ=
|
||||
golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k=
|
||||
golang.org/x/term v0.6.0/go.mod h1:m6U89DPEgQRMq3DNkDClhWw02AUbt2daBVO4cn4Hv9U=
|
||||
golang.org/x/term v0.11.0 h1:F9tnn/DA/Im8nCwm+fX+1/eBwi4qFjRT++MhtVC4ZX0=
|
||||
golang.org/x/term v0.11.0/go.mod h1:zC9APTIj3jG3FdV/Ons+XE1riIZXG4aZ4GTHiPZJPIU=
|
||||
golang.org/x/term v0.12.0 h1:/ZfYdc3zq+q02Rv9vGqTeSItdzZTSNDmfTi0mBAuidU=
|
||||
golang.org/x/term v0.12.0/go.mod h1:owVbMEjm3cBLCHdkQu9b1opXd4ETQWc3BhuQGKgXgvU=
|
||||
golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
@ -1337,8 +1338,8 @@ golang.org/x/text v0.3.8/go.mod h1:E6s5w1FMmriuDzIBO73fBruAKo1PCIq6d2Q6DHfQ8WQ=
|
||||
golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
|
||||
golang.org/x/text v0.6.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
|
||||
golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
|
||||
golang.org/x/text v0.12.0 h1:k+n5B8goJNdU7hSvEtMUz3d1Q6D/XW4COJSJR6fN0mc=
|
||||
golang.org/x/text v0.12.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE=
|
||||
golang.org/x/text v0.13.0 h1:ablQoSUd0tRdKxZewP80B+BaqeKJuVhuRxj/dkrun3k=
|
||||
golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE=
|
||||
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=
|
||||
|
12
hack/go.mod
12
hack/go.mod
@ -168,7 +168,7 @@ require (
|
||||
github.com/google/go-attestation v0.5.0 // indirect
|
||||
github.com/google/go-cmp v0.5.9 // indirect
|
||||
github.com/google/go-containerregistry v0.15.2 // indirect
|
||||
github.com/google/go-sev-guest v0.6.1 // indirect
|
||||
github.com/google/go-sev-guest v0.8.0 // indirect
|
||||
github.com/google/go-tpm v0.9.0 // indirect
|
||||
github.com/google/go-tpm-tools v0.4.0 // indirect
|
||||
github.com/google/go-tspi v0.3.0 // indirect
|
||||
@ -176,7 +176,7 @@ require (
|
||||
github.com/google/logger v1.1.1 // indirect
|
||||
github.com/google/s2a-go v0.1.4 // indirect
|
||||
github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 // indirect
|
||||
github.com/google/uuid v1.3.0 // indirect
|
||||
github.com/google/uuid v1.3.1 // indirect
|
||||
github.com/googleapis/enterprise-certificate-proxy v0.2.5 // indirect
|
||||
github.com/googleapis/gax-go/v2 v2.12.0 // indirect
|
||||
github.com/gophercloud/gophercloud v1.5.0 // indirect
|
||||
@ -280,13 +280,13 @@ require (
|
||||
go.starlark.net v0.0.0-20220223235035-243c74974e97 // indirect
|
||||
go.uber.org/atomic v1.11.0 // indirect
|
||||
go.uber.org/multierr v1.11.0 // indirect
|
||||
golang.org/x/crypto v0.12.0 // indirect
|
||||
golang.org/x/crypto v0.13.0 // indirect
|
||||
golang.org/x/net v0.14.0 // indirect
|
||||
golang.org/x/oauth2 v0.9.0 // indirect
|
||||
golang.org/x/sync v0.3.0 // indirect
|
||||
golang.org/x/sys v0.11.0 // indirect
|
||||
golang.org/x/term v0.11.0 // indirect
|
||||
golang.org/x/text v0.12.0 // indirect
|
||||
golang.org/x/sys v0.12.0 // indirect
|
||||
golang.org/x/term v0.12.0 // indirect
|
||||
golang.org/x/text v0.13.0 // indirect
|
||||
golang.org/x/time v0.3.0 // indirect
|
||||
golang.org/x/tools v0.10.0 // indirect
|
||||
google.golang.org/api v0.130.0 // indirect
|
||||
|
23
hack/go.sum
23
hack/go.sum
@ -496,8 +496,8 @@ github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38=
|
||||
github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
|
||||
github.com/google/go-containerregistry v0.15.2 h1:MMkSh+tjSdnmJZO7ljvEqV1DjfekB6VUEAZgy3a+TQE=
|
||||
github.com/google/go-containerregistry v0.15.2/go.mod h1:wWK+LnOv4jXMM23IT/F1wdYftGWGr47Is8CG+pmHK1Q=
|
||||
github.com/google/go-sev-guest v0.6.1 h1:NajHkAaLqN9/aW7bCFSUplUMtDgk2+HcN7jC2btFtk0=
|
||||
github.com/google/go-sev-guest v0.6.1/go.mod h1:UEi9uwoPbLdKGl1QHaq1G8pfCbQ4QP0swWX4J0k6r+Q=
|
||||
github.com/google/go-sev-guest v0.8.0 h1:IIZIqdcMJXgTm1nMvId442OUpYebbWDWa9bi9/lUUwc=
|
||||
github.com/google/go-sev-guest v0.8.0/go.mod h1:hc1R4R6f8+NcJwITs0L90fYWTsBpd1Ix+Gur15sqHDs=
|
||||
github.com/google/go-tpm v0.9.0 h1:sQF6YqWMi+SCXpsmS3fd21oPy/vSddwZry4JnmltHVk=
|
||||
github.com/google/go-tpm v0.9.0/go.mod h1:FkNVkc6C+IsvDI9Jw1OveJmxGZUUaKxtrpOS47QWKfU=
|
||||
github.com/google/go-tpm-tools v0.4.0 h1:bYRZAUvQEmn11WTKCkTLRCCv4aTlOBgBBeqCK0ABT2A=
|
||||
@ -533,8 +533,9 @@ github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510/go.mod h1:pupxD2MaaD3
|
||||
github.com/google/uuid v1.0.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||
github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||
github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||
github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I=
|
||||
github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||
github.com/google/uuid v1.3.1 h1:KjJaJ9iWZ3jOFZIf1Lqf4laDRCasjl0BCmnEGxkdLb4=
|
||||
github.com/google/uuid v1.3.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||
github.com/googleapis/enterprise-certificate-proxy v0.2.5 h1:UR4rDjcgpgEnqpIEvkiqTYKBCKLNmlge2eVjoZfySzM=
|
||||
github.com/googleapis/enterprise-certificate-proxy v0.2.5/go.mod h1:RxW0N9901Cko1VOCW3SXCpWP+mlIEkk2tP7jnHy9a3w=
|
||||
github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg=
|
||||
@ -1068,8 +1069,8 @@ golang.org/x/crypto v0.3.0/go.mod h1:hebNnKkNXi2UzZN1eVRvBB7co0a+JxK6XbPiWVs/3J4
|
||||
golang.org/x/crypto v0.5.0/go.mod h1:NK/OQwhpMQP3MwtdjgLlYHnH9ebylxKWv3e0fK+mkQU=
|
||||
golang.org/x/crypto v0.6.0/go.mod h1:OFC/31mSvZgRz0V1QTNCzfAI1aIRzbiufJtkMIlEp58=
|
||||
golang.org/x/crypto v0.7.0/go.mod h1:pYwdfH91IfpZVANVyUOhSIPZaFoJGxTFbZhFTx+dXZU=
|
||||
golang.org/x/crypto v0.12.0 h1:tFM/ta59kqch6LlvYnPa0yx5a83cL2nHflFhYKvv9Yk=
|
||||
golang.org/x/crypto v0.12.0/go.mod h1:NF0Gs7EO5K4qLn+Ylc+fih8BSTeIjAP05siRnAh98yw=
|
||||
golang.org/x/crypto v0.13.0 h1:mvySKfSWJ+UKUii46M40LOvyWfN0s2U+46/jDd0e6Ck=
|
||||
golang.org/x/crypto v0.13.0/go.mod h1:y6Z2r+Rw4iayiXXAIxJIDAJ1zMW4yaTpebo8fPOliYc=
|
||||
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
||||
golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
||||
golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8=
|
||||
@ -1269,16 +1270,16 @@ golang.org/x/sys v0.3.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.4.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.11.0 h1:eG7RXZHdqOJ1i+0lgLgCpSXAp6M3LYlAo6osgSi0xOM=
|
||||
golang.org/x/sys v0.11.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.12.0 h1:CM0HF96J0hcLAwsHPJZjfdNzs0gftsLfgKt57wWHJ0o=
|
||||
golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
|
||||
golang.org/x/term v0.2.0/go.mod h1:TVmDHMZPmdnySmBfhjOoOdhjzdE1h4u1VwSiw2l1Nuc=
|
||||
golang.org/x/term v0.4.0/go.mod h1:9P2UbLfCdcvo3p/nzKvsmas4TnlujnuoV9hGgYzW1lQ=
|
||||
golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k=
|
||||
golang.org/x/term v0.6.0/go.mod h1:m6U89DPEgQRMq3DNkDClhWw02AUbt2daBVO4cn4Hv9U=
|
||||
golang.org/x/term v0.11.0 h1:F9tnn/DA/Im8nCwm+fX+1/eBwi4qFjRT++MhtVC4ZX0=
|
||||
golang.org/x/term v0.11.0/go.mod h1:zC9APTIj3jG3FdV/Ons+XE1riIZXG4aZ4GTHiPZJPIU=
|
||||
golang.org/x/term v0.12.0 h1:/ZfYdc3zq+q02Rv9vGqTeSItdzZTSNDmfTi0mBAuidU=
|
||||
golang.org/x/term v0.12.0/go.mod h1:owVbMEjm3cBLCHdkQu9b1opXd4ETQWc3BhuQGKgXgvU=
|
||||
golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
@ -1293,8 +1294,8 @@ golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
|
||||
golang.org/x/text v0.6.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
|
||||
golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
|
||||
golang.org/x/text v0.8.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=
|
||||
golang.org/x/text v0.12.0 h1:k+n5B8goJNdU7hSvEtMUz3d1Q6D/XW4COJSJR6fN0mc=
|
||||
golang.org/x/text v0.12.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE=
|
||||
golang.org/x/text v0.13.0 h1:ablQoSUd0tRdKxZewP80B+BaqeKJuVhuRxj/dkrun3k=
|
||||
golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE=
|
||||
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=
|
||||
|
@ -4,7 +4,6 @@ load("//bazel/go:go_test.bzl", "go_test")
|
||||
go_library(
|
||||
name = "snp",
|
||||
srcs = [
|
||||
"errors.go",
|
||||
"imds.go",
|
||||
"issuer.go",
|
||||
"maa.go",
|
||||
@ -20,8 +19,13 @@ go_library(
|
||||
"//internal/attestation/vtpm",
|
||||
"//internal/cloud/azure",
|
||||
"//internal/config",
|
||||
"//internal/crypto",
|
||||
"@com_github_edgelesssys_go_azguestattestation//maa",
|
||||
"@com_github_google_go_sev_guest//abi",
|
||||
"@com_github_google_go_sev_guest//kds",
|
||||
"@com_github_google_go_sev_guest//proto/sevsnp",
|
||||
"@com_github_google_go_sev_guest//validate",
|
||||
"@com_github_google_go_sev_guest//verify",
|
||||
"@com_github_google_go_sev_guest//verify/trust",
|
||||
"@com_github_google_go_tpm//legacy/tpm2",
|
||||
"@com_github_google_go_tpm_tools//client",
|
||||
"@com_github_google_go_tpm_tools//proto/attest",
|
||||
@ -42,12 +46,19 @@ go_test(
|
||||
"//conditions:default": ["disable_tpm_simulator"],
|
||||
}),
|
||||
deps = [
|
||||
"//internal/attestation",
|
||||
"//internal/attestation/azure/snp/testdata",
|
||||
"//internal/attestation/idkeydigest",
|
||||
"//internal/attestation/simulator",
|
||||
"//internal/attestation/vtpm",
|
||||
"//internal/config",
|
||||
"//internal/logger",
|
||||
"@com_github_edgelesssys_go_azguestattestation//maa",
|
||||
"@com_github_google_go_sev_guest//abi",
|
||||
"@com_github_google_go_sev_guest//kds",
|
||||
"@com_github_google_go_sev_guest//proto/sevsnp",
|
||||
"@com_github_google_go_sev_guest//validate",
|
||||
"@com_github_google_go_sev_guest//verify",
|
||||
"@com_github_google_go_tpm//legacy/tpm2",
|
||||
"@com_github_google_go_tpm_tools//client",
|
||||
"@com_github_google_go_tpm_tools//proto/attest",
|
||||
|
@ -1,76 +0,0 @@
|
||||
/*
|
||||
Copyright (c) Edgeless Systems GmbH
|
||||
|
||||
SPDX-License-Identifier: AGPL-3.0-only
|
||||
*/
|
||||
|
||||
package snp
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
)
|
||||
|
||||
type signatureError struct {
|
||||
innerError error
|
||||
}
|
||||
|
||||
func (e *signatureError) Unwrap() error {
|
||||
return e.innerError
|
||||
}
|
||||
|
||||
func (e *signatureError) Error() string {
|
||||
return fmt.Sprintf("signature validation failed: %v", e.innerError)
|
||||
}
|
||||
|
||||
type askError struct {
|
||||
innerError error
|
||||
}
|
||||
|
||||
func (e *askError) Unwrap() error {
|
||||
return e.innerError
|
||||
}
|
||||
|
||||
func (e *askError) Error() string {
|
||||
return fmt.Sprintf("validating ASK: %v", e.innerError)
|
||||
}
|
||||
|
||||
type vcekError struct {
|
||||
innerError error
|
||||
}
|
||||
|
||||
func (e *vcekError) Unwrap() error {
|
||||
return e.innerError
|
||||
}
|
||||
|
||||
func (e *vcekError) Error() string {
|
||||
return fmt.Sprintf("validating VCEK: %v", e.innerError)
|
||||
}
|
||||
|
||||
type idKeyError struct {
|
||||
encounteredValue []byte
|
||||
expectedValues [][]byte
|
||||
}
|
||||
|
||||
func (e *idKeyError) Unwrap() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (e *idKeyError) Error() string {
|
||||
return fmt.Sprintf("accepted idkeydigest list %x doesn't contain reported idkeydigest %x", e.expectedValues, e.encounteredValue)
|
||||
}
|
||||
|
||||
type versionError struct {
|
||||
expectedType string
|
||||
excpectedVersion tcbVersion
|
||||
}
|
||||
|
||||
func (e *versionError) Unwrap() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (e *versionError) Error() string {
|
||||
return fmt.Sprintf("invalid %s version: %x", e.expectedType, e.excpectedVersion)
|
||||
}
|
||||
|
||||
var errDebugEnabled = errors.New("SNP report indicates debugging, expected no debugging")
|
@ -66,7 +66,7 @@ func (i *Issuer) getInstanceInfo(ctx context.Context, tpm io.ReadWriteCloser, us
|
||||
}
|
||||
|
||||
instanceInfo := azureInstanceInfo{
|
||||
Vcek: params.VcekCert,
|
||||
VCEK: params.VcekCert,
|
||||
CertChain: params.VcekChain,
|
||||
AttestationReport: params.SNPReport,
|
||||
RuntimeData: params.RuntimeData,
|
||||
|
@ -103,7 +103,7 @@ func TestGetSNPAttestation(t *testing.T) {
|
||||
err = json.Unmarshal(attestationJSON, &instanceInfo)
|
||||
require.NoError(err)
|
||||
|
||||
assert.Equal(params.VcekCert, instanceInfo.Vcek)
|
||||
assert.Equal(params.VcekCert, instanceInfo.VCEK)
|
||||
assert.Equal(params.VcekChain, instanceInfo.CertChain)
|
||||
assert.Equal(params.SNPReport, instanceInfo.AttestationReport)
|
||||
assert.Equal(params.RuntimeData, instanceInfo.RuntimeData)
|
||||
|
15
internal/attestation/azure/snp/testdata/BUILD.bazel
vendored
Normal file
15
internal/attestation/azure/snp/testdata/BUILD.bazel
vendored
Normal file
@ -0,0 +1,15 @@
|
||||
load("@io_bazel_rules_go//go:def.bzl", "go_library")
|
||||
|
||||
go_library(
|
||||
name = "testdata",
|
||||
srcs = ["testdata.go"],
|
||||
embedsrcs = [
|
||||
"attestation.bin",
|
||||
"vcek.cert",
|
||||
"certchain.pem",
|
||||
"runtimedata.bin",
|
||||
"vcek.pem",
|
||||
],
|
||||
importpath = "github.com/edgelesssys/constellation/v2/internal/attestation/azure/snp/testdata",
|
||||
visibility = ["//:__subpackages__"],
|
||||
)
|
BIN
internal/attestation/azure/snp/testdata/attestation.bin
vendored
Normal file
BIN
internal/attestation/azure/snp/testdata/attestation.bin
vendored
Normal file
Binary file not shown.
74
internal/attestation/azure/snp/testdata/certchain.pem
vendored
Normal file
74
internal/attestation/azure/snp/testdata/certchain.pem
vendored
Normal file
@ -0,0 +1,74 @@
|
||||
-----BEGIN CERTIFICATE-----
|
||||
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
|
||||
-----END CERTIFICATE-----
|
||||
-----BEGIN CERTIFICATE-----
|
||||
MIIGYzCCBBKgAwIBAgIDAQAAMEYGCSqGSIb3DQEBCjA5oA8wDQYJYIZIAWUDBAIC
|
||||
BQChHDAaBgkqhkiG9w0BAQgwDQYJYIZIAWUDBAICBQCiAwIBMKMDAgEBMHsxFDAS
|
||||
BgNVBAsMC0VuZ2luZWVyaW5nMQswCQYDVQQGEwJVUzEUMBIGA1UEBwwLU2FudGEg
|
||||
Q2xhcmExCzAJBgNVBAgMAkNBMR8wHQYDVQQKDBZBZHZhbmNlZCBNaWNybyBEZXZp
|
||||
Y2VzMRIwEAYDVQQDDAlBUkstTWlsYW4wHhcNMjAxMDIyMTcyMzA1WhcNNDUxMDIy
|
||||
MTcyMzA1WjB7MRQwEgYDVQQLDAtFbmdpbmVlcmluZzELMAkGA1UEBhMCVVMxFDAS
|
||||
BgNVBAcMC1NhbnRhIENsYXJhMQswCQYDVQQIDAJDQTEfMB0GA1UECgwWQWR2YW5j
|
||||
ZWQgTWljcm8gRGV2aWNlczESMBAGA1UEAwwJQVJLLU1pbGFuMIICIjANBgkqhkiG
|
||||
9w0BAQEFAAOCAg8AMIICCgKCAgEA0Ld52RJOdeiJlqK2JdsVmD7FktuotWwX1fNg
|
||||
W41XY9Xz1HEhSUmhLz9Cu9DHRlvgJSNxbeYYsnJfvyjx1MfU0V5tkKiU1EesNFta
|
||||
1kTA0szNisdYc9isqk7mXT5+KfGRbfc4V/9zRIcE8jlHN61S1ju8X93+6dxDUrG2
|
||||
SzxqJ4BhqyYmUDruPXJSX4vUc01P7j98MpqOS95rORdGHeI52Naz5m2B+O+vjsC0
|
||||
60d37jY9LFeuOP4Meri8qgfi2S5kKqg/aF6aPtuAZQVR7u3KFYXP59XmJgtcog05
|
||||
gmI0T/OitLhuzVvpZcLph0odh/1IPXqx3+MnjD97A7fXpqGd/y8KxX7jksTEzAOg
|
||||
bKAeam3lm+3yKIcTYMlsRMXPcjNbIvmsBykD//xSniusuHBkgnlENEWx1UcbQQrs
|
||||
+gVDkuVPhsnzIRNgYvM48Y+7LGiJYnrmE8xcrexekBxrva2V9TJQqnN3Q53kt5vi
|
||||
Qi3+gCfmkwC0F0tirIZbLkXPrPwzZ0M9eNxhIySb2npJfgnqz55I0u33wh4r0ZNQ
|
||||
eTGfw03MBUtyuzGesGkcw+loqMaq1qR4tjGbPYxCvpCq7+OgpCCoMNit2uLo9M18
|
||||
fHz10lOMT8nWAUvRZFzteXCm+7PHdYPlmQwUw3LvenJ/ILXoQPHfbkH0CyPfhl1j
|
||||
WhJFZasCAwEAAaN+MHwwDgYDVR0PAQH/BAQDAgEGMB0GA1UdDgQWBBSFrBrRQ/fI
|
||||
rFXUxR1BSKvVeErUUzAPBgNVHRMBAf8EBTADAQH/MDoGA1UdHwQzMDEwL6AtoCuG
|
||||
KWh0dHBzOi8va2RzaW50Zi5hbWQuY29tL3ZjZWsvdjEvTWlsYW4vY3JsMEYGCSqG
|
||||
SIb3DQEBCjA5oA8wDQYJYIZIAWUDBAICBQChHDAaBgkqhkiG9w0BAQgwDQYJYIZI
|
||||
AWUDBAICBQCiAwIBMKMDAgEBA4ICAQC6m0kDp6zv4Ojfgy+zleehsx6ol0ocgVel
|
||||
ETobpx+EuCsqVFRPK1jZ1sp/lyd9+0fQ0r66n7kagRk4Ca39g66WGTJMeJdqYriw
|
||||
STjjDCKVPSesWXYPVAyDhmP5n2v+BYipZWhpvqpaiO+EGK5IBP+578QeW/sSokrK
|
||||
dHaLAxG2LhZxj9aF73fqC7OAJZ5aPonw4RE299FVarh1Tx2eT3wSgkDgutCTB1Yq
|
||||
zT5DuwvAe+co2CIVIzMDamYuSFjPN0BCgojl7V+bTou7dMsqIu/TW/rPCX9/EUcp
|
||||
KGKqPQ3P+N9r1hjEFY1plBg93t53OOo49GNI+V1zvXPLI6xIFVsh+mto2RtgEX/e
|
||||
pmMKTNN6psW88qg7c1hTWtN6MbRuQ0vm+O+/2tKBF2h8THb94OvvHHoFDpbCELlq
|
||||
HnIYhxy0YKXGyaW1NjfULxrrmxVW4wcn5E8GddmvNa6yYm8scJagEi13mhGu4Jqh
|
||||
3QU3sf8iUSUr09xQDwHtOQUVIqx4maBZPBtSMf+qUDtjXSSq8lfWcd8bLr9mdsUn
|
||||
JZJ0+tuPMKmBnSH860llKk+VpVQsgqbzDIvOLvD6W1Umq25boxCYJ+TuBoa4s+HH
|
||||
CViAvgT9kf/rBq1d+ivj6skkHxuzcxbk1xv6ZGxrteJxVH7KlX7YRdZ6eARKwLe4
|
||||
AFZEAwoKCQ==
|
||||
-----END CERTIFICATE-----
|
1
internal/attestation/azure/snp/testdata/runtimedata.bin
vendored
Normal file
1
internal/attestation/azure/snp/testdata/runtimedata.bin
vendored
Normal file
@ -0,0 +1 @@
|
||||
{"keys":[{"kid":"HCLAkPub","key_ops":["encrypt"],"kty":"RSA","e":"AQAB","n":"tyFqvAAAf2GFelkW7VcRhJnA2YvY6LjBzeUN2vaMZnZth_tFnWMkK5AXtusyCNel3uip3VGZzTaz5X2tGVjGrs-MVHcap9QdwqUXVW3g9OQ_tEbixcx7-xblUJQkGEQfnbbSdnPI2lvLzOs1Z_0vjeDAxvSQrmags6nY-cJAWH-pgDVJyHtpsUSs_QBWklazDso5WHmnMt9s9MuilWXox0RSyXnUeaQyhY1ju7RTScRnVXuNy67z_EJnwM92drwFb8AUd0SJ_9ohvEYl4aZRDECGo0VrjcSHU-JGJeuWC5VhDBR5EOoCVBBgqe9e83v_lJxI3WLe2ovSIZIIzAmbSQ"}],"vm-configuration":{"console-enabled":true,"current-time":1661455391,"secure-boot":false,"tpm-enabled":true,"vmUniqueId":"B6C98C3B-4EC7-4DA6-BD2F-7D98D20D7B75"}}
|
35
internal/attestation/azure/snp/testdata/testdata.go
vendored
Normal file
35
internal/attestation/azure/snp/testdata/testdata.go
vendored
Normal file
@ -0,0 +1,35 @@
|
||||
/*
|
||||
Copyright (c) Edgeless Systems GmbH
|
||||
|
||||
SPDX-License-Identifier: AGPL-3.0-only
|
||||
*/
|
||||
|
||||
// Package testdata contains testing data for an attestation process.
|
||||
package testdata
|
||||
|
||||
import _ "embed"
|
||||
|
||||
// AttestationBytes is an example attestation report from a Constellation VM.
|
||||
//
|
||||
//go:embed attestation.bin
|
||||
var AttestationReport []byte
|
||||
|
||||
// AzureThimVCEK is an example VCEK certificate (PEM, as returned from Azure THIM) for the AttestationReport.
|
||||
//
|
||||
//go:embed vcek.pem
|
||||
var AzureThimVCEK []byte
|
||||
|
||||
// AmdKdsVCEK is an example VCEK certificate (DER, as returned from AMD KDS) for the AttestationReport.
|
||||
//
|
||||
//go:embed vcek.cert
|
||||
var AmdKdsVCEK []byte
|
||||
|
||||
// RuntimeData is an example runtime data from the TPM for the AttestationReport.
|
||||
//
|
||||
//go:embed runtimedata.bin
|
||||
var RuntimeData []byte
|
||||
|
||||
// CertChain is a valid certificate chain (PEM, as returned from Azure THIM) for the VCEK certificate.
|
||||
//
|
||||
//go:embed certchain.pem
|
||||
var CertChain []byte
|
BIN
internal/attestation/azure/snp/testdata/vcek.cert
vendored
Normal file
BIN
internal/attestation/azure/snp/testdata/vcek.cert
vendored
Normal file
Binary file not shown.
31
internal/attestation/azure/snp/testdata/vcek.pem
vendored
Normal file
31
internal/attestation/azure/snp/testdata/vcek.pem
vendored
Normal file
@ -0,0 +1,31 @@
|
||||
-----BEGIN CERTIFICATE-----
|
||||
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
|
||||
8H3kABPv6hqrFftRNbargQ==
|
||||
-----END CERTIFICATE-----
|
@ -12,20 +12,24 @@ import (
|
||||
"crypto"
|
||||
"crypto/sha256"
|
||||
"crypto/x509"
|
||||
"encoding/asn1"
|
||||
"encoding/base64"
|
||||
"encoding/binary"
|
||||
"encoding/json"
|
||||
"encoding/pem"
|
||||
"errors"
|
||||
"fmt"
|
||||
"math/big"
|
||||
|
||||
"github.com/edgelesssys/constellation/v2/internal/attestation"
|
||||
"github.com/edgelesssys/constellation/v2/internal/attestation/idkeydigest"
|
||||
"github.com/edgelesssys/constellation/v2/internal/attestation/variant"
|
||||
"github.com/edgelesssys/constellation/v2/internal/attestation/vtpm"
|
||||
"github.com/edgelesssys/constellation/v2/internal/config"
|
||||
internalCrypto "github.com/edgelesssys/constellation/v2/internal/crypto"
|
||||
"github.com/google/go-sev-guest/abi"
|
||||
"github.com/google/go-sev-guest/kds"
|
||||
spb "github.com/google/go-sev-guest/proto/sevsnp"
|
||||
"github.com/google/go-sev-guest/validate"
|
||||
"github.com/google/go-sev-guest/verify"
|
||||
"github.com/google/go-sev-guest/verify/trust"
|
||||
"github.com/google/go-tpm-tools/proto/attest"
|
||||
"github.com/google/go-tpm/legacy/tpm2"
|
||||
)
|
||||
@ -36,251 +40,359 @@ type Validator struct {
|
||||
*vtpm.Validator
|
||||
hclValidator hclAkValidator
|
||||
maa maaValidator
|
||||
getter trust.HTTPSGetter
|
||||
|
||||
attestationVerifier attestationVerifier
|
||||
attestationValidator attestationValidator
|
||||
|
||||
config *config.AzureSEVSNP
|
||||
|
||||
log attestation.Logger
|
||||
}
|
||||
|
||||
type attestationVerifier interface {
|
||||
SNPAttestation(attestation *spb.Attestation, options *verify.Options) error
|
||||
}
|
||||
|
||||
type attestationValidator interface {
|
||||
SNPAttestation(attestation *spb.Attestation, options *validate.Options) error
|
||||
}
|
||||
|
||||
type attestationVerifierImpl struct{}
|
||||
|
||||
// SNPAttestation verifies the report signature, the VCEK certificate, as well as the certificate chain of the attestation report.
|
||||
func (attestationVerifierImpl) SNPAttestation(attestation *spb.Attestation, options *verify.Options) error {
|
||||
return verify.SnpAttestation(attestation, options)
|
||||
}
|
||||
|
||||
type attestationValidatorImpl struct{}
|
||||
|
||||
// SNPAttestation validates the attestation report against the given set of constraints.
|
||||
func (attestationValidatorImpl) SNPAttestation(attestation *spb.Attestation, options *validate.Options) error {
|
||||
return validate.SnpAttestation(attestation, options)
|
||||
}
|
||||
|
||||
// NewValidator initializes a new Azure validator with the provided PCR values.
|
||||
func NewValidator(cfg *config.AzureSEVSNP, log attestation.Logger) *Validator {
|
||||
if log == nil {
|
||||
log = nopAttestationLogger{}
|
||||
}
|
||||
v := &Validator{
|
||||
hclValidator: &azureInstanceInfo{},
|
||||
maa: newMAAClient(),
|
||||
config: cfg,
|
||||
log: log,
|
||||
hclValidator: &azureInstanceInfo{},
|
||||
maa: newMAAClient(),
|
||||
config: cfg,
|
||||
log: log,
|
||||
getter: trust.DefaultHTTPSGetter(),
|
||||
attestationVerifier: attestationVerifierImpl{},
|
||||
attestationValidator: attestationValidatorImpl{},
|
||||
}
|
||||
v.Validator = vtpm.NewValidator(
|
||||
cfg.Measurements,
|
||||
v.getTrustedKey,
|
||||
validateCVM,
|
||||
// stub, since SEV-SNP attestation is already verified in trustedKeyFromSNP().
|
||||
func(vtpm.AttestationDocument, *attest.MachineState) error {
|
||||
return nil
|
||||
},
|
||||
log,
|
||||
)
|
||||
return v
|
||||
}
|
||||
|
||||
// validateCVM is a stub, since SEV-SNP attestation is already verified in trustedKeyFromSNP().
|
||||
func validateCVM(vtpm.AttestationDocument, *attest.MachineState) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func newSNPReportFromBytes(reportRaw []byte) (snpAttestationReport, error) {
|
||||
var report snpAttestationReport
|
||||
if err := binary.Read(bytes.NewReader(reportRaw), binary.LittleEndian, &report); err != nil {
|
||||
return snpAttestationReport{}, fmt.Errorf("reading attestation report: %w", err)
|
||||
}
|
||||
|
||||
return report, nil
|
||||
}
|
||||
|
||||
func reverseEndian(b []byte) {
|
||||
for i := 0; i < len(b)/2; i++ {
|
||||
b[i], b[len(b)-i-1] = b[len(b)-i-1], b[i]
|
||||
}
|
||||
}
|
||||
|
||||
// getTrustedKey establishes trust in the given public key.
|
||||
// It does so by verifying the SNP attestation statement in instanceInfo.
|
||||
// It does so by verifying the SNP attestation document.
|
||||
func (v *Validator) getTrustedKey(ctx context.Context, attDoc vtpm.AttestationDocument, extraData []byte) (crypto.PublicKey, error) {
|
||||
// transform the instanceInfo received from Microsoft into a verifiable attestation report format.
|
||||
var instanceInfo azureInstanceInfo
|
||||
if err := json.Unmarshal(attDoc.InstanceInfo, &instanceInfo); err != nil {
|
||||
return nil, fmt.Errorf("unmarshalling instanceInfoRaw: %w", err)
|
||||
return nil, fmt.Errorf("unmarshalling instanceInfo: %w", err)
|
||||
}
|
||||
|
||||
report, err := newSNPReportFromBytes(instanceInfo.AttestationReport)
|
||||
att, err := instanceInfo.attestationWithCerts(v.log, v.getter)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("parsing attestation report: %w", err)
|
||||
}
|
||||
|
||||
vcek, err := v.validateVCEK(instanceInfo.Vcek, instanceInfo.CertChain)
|
||||
// Verify the attestation report's certificates.
|
||||
trustedArk := x509.Certificate(v.config.AMDRootKey) // ARK, specified in Constellation config.
|
||||
ask, err := x509.ParseCertificate(att.CertificateChain.AskCert) // ASK, as reported from THIM / KDS.
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("validating VCEK: %w", err)
|
||||
return nil, fmt.Errorf("parsing ASK certificate: %w", err)
|
||||
}
|
||||
|
||||
if err := v.validateSNPReport(ctx, vcek, report, instanceInfo.MAAToken, extraData); err != nil {
|
||||
return nil, fmt.Errorf("validating SNP report: %w", err)
|
||||
verifyOpts := &verify.Options{
|
||||
TrustedRoots: map[string][]*trust.AMDRootCerts{
|
||||
"Milan": {
|
||||
{
|
||||
Product: "Milan",
|
||||
ProductCerts: &trust.ProductCerts{
|
||||
Ask: ask,
|
||||
Ark: &trustedArk,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
if err := v.attestationVerifier.SNPAttestation(att, verifyOpts); err != nil {
|
||||
return nil, fmt.Errorf("verifying SNP attestation: %w", err)
|
||||
}
|
||||
|
||||
// Checks if the attestation report matches the given constraints.
|
||||
// Some constraints are implicitly checked by validate.SnpAttestation:
|
||||
// - the report is not expired
|
||||
if err := v.attestationValidator.SNPAttestation(att, &validate.Options{
|
||||
GuestPolicy: abi.SnpPolicy{
|
||||
Debug: false, // Debug means the VM can be decrypted by the host for debugging purposes and thus is not allowed.
|
||||
SMT: true, // Allow Simultaneous Multi-Threading (SMT). Normally, we would want to disable SMT
|
||||
// but Azure does not allow to disable it.
|
||||
},
|
||||
VMPL: new(int), // Checks that Virtual Machine Privilege Level (VMPL) is 0.
|
||||
// This checks that the reported TCB version is equal or greater than the minimum specified in the config.
|
||||
MinimumTCB: kds.TCBParts{
|
||||
BlSpl: v.config.BootloaderVersion.Value, // Bootloader
|
||||
TeeSpl: v.config.TEEVersion.Value, // TEE (Secure OS)
|
||||
SnpSpl: v.config.SNPVersion.Value, // SNP
|
||||
UcodeSpl: v.config.MicrocodeVersion.Value, // Microcode
|
||||
},
|
||||
// This checks that the reported LaunchTCB version is equal or greater than the minimum specified in the config.
|
||||
MinimumLaunchTCB: kds.TCBParts{
|
||||
BlSpl: v.config.BootloaderVersion.Value, // Bootloader
|
||||
TeeSpl: v.config.TEEVersion.Value, // TEE (Secure OS)
|
||||
SnpSpl: v.config.SNPVersion.Value, // SNP
|
||||
UcodeSpl: v.config.MicrocodeVersion.Value, // Microcode
|
||||
},
|
||||
// Check that CurrentTCB >= CommittedTCB.
|
||||
PermitProvisionalFirmware: true,
|
||||
// Check if the IDKey hash in the report is in the list of accepted hashes.
|
||||
TrustedIDKeyHashes: v.config.FirmwareSignerConfig.AcceptedKeyDigests,
|
||||
// The IDKey hash should not be checked if the enforcement policy is set to MAAFallback or WarnOnly to prevent
|
||||
// an error from being returned because of the TrustedIDKeyHashes validation. In this case, we should perform a
|
||||
// custom check of the MAA-specific values later. Right now, this is a double check, since a custom MAA check
|
||||
// is performed either way.
|
||||
RequireIDBlock: v.config.FirmwareSignerConfig.EnforcementPolicy == idkeydigest.Equal,
|
||||
}); err != nil {
|
||||
return nil, fmt.Errorf("validating SNP attestation: %w", err)
|
||||
}
|
||||
// Custom check of the IDKeyDigests, taking care of the WarnOnly / MAAFallback cases,
|
||||
// but also double-checking the IDKeyDigests if the enforcement policy is set to Equal.
|
||||
if err := v.checkIDKeyDigest(ctx, att, instanceInfo.MAAToken, extraData); err != nil {
|
||||
return nil, fmt.Errorf("checking IDKey digests: %w", err)
|
||||
}
|
||||
|
||||
// Decode the public area of the attestation key and validate its trustworthiness.
|
||||
pubArea, err := tpm2.DecodePublic(attDoc.Attestation.AkPub)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if err = v.hclValidator.validateAk(instanceInfo.RuntimeData, report.ReportData[:], pubArea.RSAParameters); err != nil {
|
||||
if err = v.hclValidator.validateAk(instanceInfo.RuntimeData, att.Report.ReportData, pubArea.RSAParameters); err != nil {
|
||||
return nil, fmt.Errorf("validating HCLAkPub: %w", err)
|
||||
}
|
||||
|
||||
return pubArea.Key()
|
||||
}
|
||||
|
||||
// validateVCEK takes the PEM-encoded X509 certificate VCEK, ASK and ARK and verifies the integrity of the chain.
|
||||
// ARK (hardcoded) validates ASK (cloud metadata API) validates VCEK (cloud metadata API).
|
||||
func (v *Validator) validateVCEK(vcekRaw []byte, certChain []byte) (*x509.Certificate, error) {
|
||||
vcek, err := internalCrypto.PemToX509Cert(vcekRaw)
|
||||
// checkIDKeyDigest validates the IDKeyDigest in the given attestation report against the accepted IDKeyDigests in the
|
||||
// validator's config. If an IDKeyDigest is present in the report that is not in the accepted IDKeyDigests, the validation proceeds
|
||||
// according to the enforcement policy. If the enforcement policy is set to MAAFallback, the maaToken is validated against the MAA.
|
||||
// If the enforcement policy is set to WarnOnly, a warning is logged. If the enforcement policy is set to neither WarnOnly or MAAFallback, an
|
||||
// error is returned.
|
||||
func (v *Validator) checkIDKeyDigest(ctx context.Context, report *spb.Attestation, maaToken string, extraData []byte) error {
|
||||
for _, digest := range v.config.FirmwareSignerConfig.AcceptedKeyDigests {
|
||||
if bytes.Equal(digest, report.Report.IdKeyDigest) {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
// IDKeyDigest that was not expected is present, check the enforcement policy and verify against
|
||||
// the MAA if necessary.
|
||||
switch v.config.FirmwareSignerConfig.EnforcementPolicy {
|
||||
case idkeydigest.MAAFallback:
|
||||
v.log.Infof(
|
||||
"Configured idkeydigests %x don't contain reported idkeydigest %x, falling back to MAA validation",
|
||||
v.config.FirmwareSignerConfig.AcceptedKeyDigests,
|
||||
report.Report.IdKeyDigest,
|
||||
)
|
||||
return v.maa.validateToken(ctx, v.config.FirmwareSignerConfig.MAAURL, maaToken, extraData)
|
||||
case idkeydigest.WarnOnly:
|
||||
v.log.Warnf(
|
||||
"Configured idkeydigests %x don't contain reported idkeydigest %x",
|
||||
v.config.FirmwareSignerConfig.AcceptedKeyDigests,
|
||||
report.Report.IdKeyDigest,
|
||||
)
|
||||
default:
|
||||
return fmt.Errorf(
|
||||
"configured idkeydigests %x don't contain reported idkeydigest %x",
|
||||
v.config.FirmwareSignerConfig.AcceptedKeyDigests,
|
||||
report.Report.IdKeyDigest,
|
||||
)
|
||||
}
|
||||
|
||||
// No IDKeyDigest that was not expected is present.
|
||||
return nil
|
||||
}
|
||||
|
||||
// azureInstanceInfo contains the necessary information to establish trust in
|
||||
// an Azure CVM.
|
||||
type azureInstanceInfo struct {
|
||||
// VCEK is the PEM-encoded VCEK certificate for the attestation report.
|
||||
VCEK []byte
|
||||
// CertChain is the PEM-encoded certificate chain for the attestation report.
|
||||
CertChain []byte
|
||||
// AttestationReport is the attestation report from the vTPM (NVRAM) of the CVM.
|
||||
AttestationReport []byte
|
||||
// RuntimeData is the Azure runtime data from the vTPM (NVRAM) of the CVM.
|
||||
RuntimeData []byte
|
||||
// MAAToken is the token of the MAA for the attestation report, used as a fallback
|
||||
// if the IDKeyDigest cannot be verified.
|
||||
MAAToken string
|
||||
}
|
||||
|
||||
// attestationWithCerts returns a formatted version of the attestation report and its certificates from the instanceInfo.
|
||||
// if the VCEK certificate or the certificate chain is not present, the given getter is used to retrieve them
|
||||
// from the AMD KDS.
|
||||
func (a *azureInstanceInfo) attestationWithCerts(logger attestation.Logger, getter trust.HTTPSGetter) (*spb.Attestation, error) {
|
||||
report, err := abi.ReportToProto(a.AttestationReport)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("loading vcek: %w", err)
|
||||
return nil, fmt.Errorf("converting report to proto: %w", err)
|
||||
}
|
||||
|
||||
// certChain includes two PEM encoded certs. The ASK and the ARK, in that order.
|
||||
ask, err := internalCrypto.PemToX509Cert(certChain)
|
||||
// Product info as reported through CPUID[EAX=1]
|
||||
sevProduct := abi.DefaultSevProduct()
|
||||
productName := kds.ProductString(sevProduct)
|
||||
|
||||
att := &spb.Attestation{
|
||||
Report: report,
|
||||
CertificateChain: &spb.CertificateChain{},
|
||||
Product: sevProduct,
|
||||
}
|
||||
|
||||
// If the VCEK certificate is present, parse it and format it.
|
||||
vcek, err := a.parseVCEK()
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("loading askPEM: %w", err)
|
||||
logger.Warnf("Error parsing VCEK: %v", err)
|
||||
}
|
||||
if vcek != nil {
|
||||
att.CertificateChain.VcekCert = vcek.Raw
|
||||
} else {
|
||||
// Otherwise, retrieve it from AMD KDS.
|
||||
logger.Infof("VCEK certificate not present, falling back to retrieving it from AMD KDS")
|
||||
vcekURL := kds.VCEKCertURL(productName, report.GetChipId(), kds.TCBVersion(report.GetReportedTcb()))
|
||||
vcek, err := getter.Get(vcekURL)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("retrieving VCEK certificate from AMD KDS: %w", err)
|
||||
}
|
||||
att.CertificateChain.VcekCert = vcek
|
||||
}
|
||||
|
||||
if err = ask.CheckSignatureFrom((*x509.Certificate)(&v.config.AMDRootKey)); err != nil {
|
||||
return nil, &askError{err}
|
||||
// If the certificate chain is present, parse it and format it.
|
||||
ask, ark, err := a.parseCertChain()
|
||||
if err != nil {
|
||||
logger.Warnf("Error parsing certificate chain: %v", err)
|
||||
}
|
||||
if ask != nil {
|
||||
att.CertificateChain.AskCert = ask.Raw
|
||||
}
|
||||
if ark != nil {
|
||||
att.CertificateChain.ArkCert = ark.Raw
|
||||
}
|
||||
// Otherwise, retrieve it from AMD KDS.
|
||||
if att.CertificateChain.AskCert == nil || att.CertificateChain.ArkCert == nil {
|
||||
logger.Infof(
|
||||
"Certificate chain not fully present (ARK present: %t, ASK present: %t), falling back to retrieving it from AMD KDS",
|
||||
(att.CertificateChain.ArkCert != nil),
|
||||
(att.CertificateChain.AskCert != nil),
|
||||
)
|
||||
kdsCertChain, err := trust.GetProductChain(productName, abi.VcekReportSigner, getter)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("retrieving certificate chain from AMD KDS: %w", err)
|
||||
}
|
||||
if att.CertificateChain.AskCert == nil {
|
||||
att.CertificateChain.AskCert = kdsCertChain.Ask.Raw
|
||||
}
|
||||
if att.CertificateChain.ArkCert == nil {
|
||||
att.CertificateChain.ArkCert = kdsCertChain.Ark.Raw
|
||||
}
|
||||
}
|
||||
|
||||
if err = vcek.CheckSignatureFrom(ask); err != nil {
|
||||
return nil, &vcekError{err}
|
||||
return att, nil
|
||||
}
|
||||
|
||||
// parseCertChain parses the certificate chain from the instanceInfo into x509-formatted ASK and ARK certificates.
|
||||
// If less than 2 certificates are present, only the present certificate is returned.
|
||||
// If more than 2 certificates are present, an error is returned.
|
||||
func (a *azureInstanceInfo) parseCertChain() (ask, ark *x509.Certificate, retErr error) {
|
||||
rest := bytes.TrimSpace(a.CertChain)
|
||||
|
||||
i := 1
|
||||
var block *pem.Block
|
||||
for block, rest = pem.Decode(rest); block != nil; block, rest = pem.Decode(rest) {
|
||||
if i > 2 {
|
||||
retErr = fmt.Errorf("parse certificate %d: more than 2 certificates in chain", i)
|
||||
return
|
||||
}
|
||||
|
||||
if block.Type != "CERTIFICATE" {
|
||||
retErr = fmt.Errorf("parse certificate %d: expected PEM block type 'CERTIFICATE', got '%s'", i, block.Type)
|
||||
return
|
||||
}
|
||||
|
||||
cert, err := x509.ParseCertificate(block.Bytes)
|
||||
if err != nil {
|
||||
retErr = fmt.Errorf("parse certificate %d: %w", i, err)
|
||||
return
|
||||
}
|
||||
|
||||
// https://www.amd.com/content/dam/amd/en/documents/epyc-technical-docs/specifications/57230.pdf
|
||||
// Table 6 and 7
|
||||
switch cert.Subject.CommonName {
|
||||
case "SEV-Milan":
|
||||
ask = cert
|
||||
case "ARK-Milan":
|
||||
ark = cert
|
||||
default:
|
||||
retErr = fmt.Errorf("parse certificate %d: unexpected subject CN %s", i, cert.Subject.CommonName)
|
||||
return
|
||||
}
|
||||
|
||||
i++
|
||||
}
|
||||
|
||||
switch {
|
||||
case i == 1:
|
||||
retErr = fmt.Errorf("no PEM blocks found")
|
||||
case len(rest) != 0:
|
||||
retErr = fmt.Errorf("remaining PEM block is not a valid certificate: %s", rest)
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
// parseVCEK parses the VCEK certificate from the instanceInfo into an x509-formatted certificate.
|
||||
// If the VCEK certificate is not present, nil is returned.
|
||||
func (a *azureInstanceInfo) parseVCEK() (*x509.Certificate, error) {
|
||||
newlinesTrimmed := bytes.TrimSpace(a.VCEK)
|
||||
if len(newlinesTrimmed) == 0 {
|
||||
// VCEK is not present.
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
block, rest := pem.Decode(newlinesTrimmed)
|
||||
if block == nil {
|
||||
return nil, fmt.Errorf("no PEM blocks found")
|
||||
}
|
||||
if len(rest) != 0 {
|
||||
return nil, fmt.Errorf("received more data than expected")
|
||||
}
|
||||
if block.Type != "CERTIFICATE" {
|
||||
return nil, fmt.Errorf("expected PEM block type 'CERTIFICATE', got '%s'", block.Type)
|
||||
}
|
||||
|
||||
vcek, err := x509.ParseCertificate(block.Bytes)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("parsing VCEK certificate: %w", err)
|
||||
}
|
||||
|
||||
return vcek, nil
|
||||
}
|
||||
|
||||
func (v *Validator) validateSNPReport(
|
||||
ctx context.Context, cert *x509.Certificate, report snpAttestationReport, maaToken string, extraData []byte,
|
||||
) error {
|
||||
if report.Policy.Debug() {
|
||||
return errDebugEnabled
|
||||
}
|
||||
|
||||
if !report.CommittedTCB.isVersion(v.config.BootloaderVersion.Value, v.config.TEEVersion.Value, v.config.SNPVersion.Value, v.config.MicrocodeVersion.Value) {
|
||||
return &versionError{"COMMITTED_TCB", report.CommittedTCB}
|
||||
}
|
||||
if report.LaunchTCB != report.CommittedTCB {
|
||||
return &versionError{"LAUNCH_TCB", report.LaunchTCB}
|
||||
}
|
||||
if !report.CommittedTCB.supersededBy(report.CurrentTCB) {
|
||||
return &versionError{"CURRENT_TCB", report.CurrentTCB}
|
||||
}
|
||||
|
||||
if err := validateVCEKExtensions(cert, report); err != nil {
|
||||
return fmt.Errorf("mismatching vcek extensions: %w", err)
|
||||
}
|
||||
|
||||
sigR := report.Signature.R[:]
|
||||
sigS := report.Signature.S[:]
|
||||
|
||||
// Table 107 in https://www.amd.com/system/files/TechDocs/56860.pdf mentions little endian signature components.
|
||||
// They come out of the certificate as big endian.
|
||||
reverseEndian(sigR)
|
||||
reverseEndian(sigS)
|
||||
|
||||
rParam := new(big.Int).SetBytes(sigR)
|
||||
sParam := new(big.Int).SetBytes(sigS)
|
||||
sequence := ecdsaSig{rParam, sParam}
|
||||
sigEncoded, err := asn1.Marshal(sequence)
|
||||
if err != nil {
|
||||
return fmt.Errorf("marshalling ecdsa signature: %w", err)
|
||||
}
|
||||
|
||||
buf := new(bytes.Buffer)
|
||||
if err = binary.Write(buf, binary.LittleEndian, report); err != nil {
|
||||
return fmt.Errorf("writing report to buf: %w", err)
|
||||
}
|
||||
// signature is only calculated from 0x0 to 0x2a0
|
||||
if err := cert.CheckSignature(x509.ECDSAWithSHA384, buf.Bytes()[:0x2a0], sigEncoded); err != nil {
|
||||
return &signatureError{err}
|
||||
}
|
||||
|
||||
hasExpectedIDKeyDigest := false
|
||||
for _, digest := range v.config.FirmwareSignerConfig.AcceptedKeyDigests {
|
||||
if bytes.Equal(digest, report.IDKeyDigest[:]) {
|
||||
hasExpectedIDKeyDigest = true
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
if !hasExpectedIDKeyDigest {
|
||||
switch v.config.FirmwareSignerConfig.EnforcementPolicy {
|
||||
case idkeydigest.MAAFallback:
|
||||
v.log.Infof(
|
||||
"configured idkeydigests %x don't contain reported idkeydigest %x, falling back to MAA validation",
|
||||
v.config.FirmwareSignerConfig.AcceptedKeyDigests,
|
||||
report.IDKeyDigest[:],
|
||||
)
|
||||
return v.maa.validateToken(ctx, v.config.FirmwareSignerConfig.MAAURL, maaToken, extraData)
|
||||
case idkeydigest.WarnOnly:
|
||||
v.log.Warnf(
|
||||
"configured idkeydigests %x don't contain reported idkeydigest %x",
|
||||
v.config.FirmwareSignerConfig.AcceptedKeyDigests,
|
||||
report.IDKeyDigest[:],
|
||||
)
|
||||
default:
|
||||
return &idKeyError{report.IDKeyDigest[:], v.config.FirmwareSignerConfig.AcceptedKeyDigests}
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// validateVCEKExtensions checks that the certificate extension values in cert match the values described in report.
|
||||
func validateVCEKExtensions(cert *x509.Certificate, report snpAttestationReport) error {
|
||||
var certVersion int
|
||||
for _, extension := range cert.Extensions {
|
||||
switch extension.Id.String() {
|
||||
// check bootloader version
|
||||
case "1.3.6.1.4.1.3704.1.3.1":
|
||||
{
|
||||
_, err := asn1.Unmarshal(extension.Value, &certVersion)
|
||||
if err != nil {
|
||||
return fmt.Errorf("unmarshalling bootloader version: %w", err)
|
||||
}
|
||||
if certVersion != int(report.CommittedTCB.Bootloader) {
|
||||
return fmt.Errorf("bootloader version %d from report does not match VCEK version %d", int(report.CommittedTCB.Bootloader), certVersion)
|
||||
}
|
||||
}
|
||||
// check TEE version
|
||||
case "1.3.6.1.4.1.3704.1.3.2":
|
||||
{
|
||||
_, err := asn1.Unmarshal(extension.Value, &certVersion)
|
||||
if err != nil {
|
||||
return fmt.Errorf("unmarshalling tee version: %w", err)
|
||||
}
|
||||
if certVersion != int(report.CommittedTCB.TEE) {
|
||||
return fmt.Errorf("bootloader version %d from report does not match VCEK version %d", int(report.CommittedTCB.TEE), certVersion)
|
||||
}
|
||||
}
|
||||
// check SNP Firmware version
|
||||
case "1.3.6.1.4.1.3704.1.3.3":
|
||||
{
|
||||
_, err := asn1.Unmarshal(extension.Value, &certVersion)
|
||||
if err != nil {
|
||||
return fmt.Errorf("unmarshalling snp version: %w", err)
|
||||
}
|
||||
if certVersion != int(report.CommittedTCB.SNP) {
|
||||
return fmt.Errorf("bootloader version %d from report does not match VCEK version %d", int(report.CommittedTCB.SNP), certVersion)
|
||||
}
|
||||
}
|
||||
// check microcode version
|
||||
case "1.3.6.1.4.1.3704.1.3.8":
|
||||
{
|
||||
_, err := asn1.Unmarshal(extension.Value, &certVersion)
|
||||
if err != nil {
|
||||
return fmt.Errorf("unmarshalling microcode version: %w", err)
|
||||
}
|
||||
if certVersion != int(report.CommittedTCB.Microcode) {
|
||||
return fmt.Errorf("bootloader version %d from report does not match VCEK version %d", int(report.CommittedTCB.Microcode), certVersion)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
type azureInstanceInfo struct {
|
||||
Vcek []byte
|
||||
CertChain []byte
|
||||
AttestationReport []byte
|
||||
RuntimeData []byte
|
||||
MAAToken string
|
||||
}
|
||||
|
||||
// validateAk validates that the attestation key from the TPM is trustworthy. The steps are:
|
||||
// 1. runtime data read from the TPM has the same sha256 digest as reported in `report_data` of the SNP report.
|
||||
// 2. modulus reported in runtime data matches modulus from key at idx 0x81000003.
|
||||
@ -336,84 +448,7 @@ type hclAkValidator interface {
|
||||
validateAk(runtimeDataRaw []byte, reportData []byte, rsaParameters *tpm2.RSAParams) error
|
||||
}
|
||||
|
||||
// Reference: https://github.com/AMDESE/sev-guest/blob/main/include/attestation.h
|
||||
type snpAttestationReport struct {
|
||||
Version uint32 // 0x000
|
||||
GuestSVN uint32 // 0x004
|
||||
Policy guestPolicy // 0x008
|
||||
FamilyID [16]byte // 0x010
|
||||
ImageID [16]byte // 0x020
|
||||
VMPL uint32 // 0x030
|
||||
SignatureAlgo uint32 // 0x034
|
||||
CurrentTCB tcbVersion // 0x038
|
||||
PlatformInfo uint64 // 0x040
|
||||
Flags uint32 // 0x048
|
||||
Reserved0 uint32 // 0x04C
|
||||
ReportData [64]byte // 0x050
|
||||
Measurement [48]byte // 0x090
|
||||
HostData [32]byte // 0x0C0
|
||||
IDKeyDigest [48]byte // 0x0E0
|
||||
AuthorKeyDigest [48]byte // 0x110
|
||||
ReportID [32]byte // 0x140
|
||||
ReportIDMa [32]byte // 0x160
|
||||
ReportedTCB tcbVersion // 0x180
|
||||
_ [24]byte // 0x188
|
||||
ChipID [64]byte // 0x1A0
|
||||
CommittedTCB tcbVersion // 0x1E0
|
||||
CurrentBuild byte // 0x1E8
|
||||
CurrentMinor byte // 0x1E9
|
||||
CurrentMajor byte // 0x1EA
|
||||
_ byte // 0x1EB
|
||||
CommittedBuild byte // 0x1EC
|
||||
CommittedMinor byte // 0x1ED
|
||||
CommittedMajor byte // 0x1EE
|
||||
_ byte // 0x1EF
|
||||
LaunchTCB tcbVersion // 0x1F0
|
||||
_ [168]byte // 0x1F8
|
||||
Signature snpSignature // 0x2A0
|
||||
}
|
||||
|
||||
type guestPolicy struct {
|
||||
AbiMinor uint8 // 0x0
|
||||
AbiMajor uint8 // 0x8
|
||||
ContainerValue byte // 0x10 - encodes the following four values:
|
||||
// Smt bool // 0x10 - bit 0 in 'ContainerValue'.
|
||||
// _ bool // 0x11 - bit 1 in 'ContainerValue'.
|
||||
// MigrateMa bool // 0x12 - bit 2 in 'ContainerValue'.
|
||||
// Debug bool // 0x13 - bit 3 in 'ContainerValue'.
|
||||
// SingleSocket bool // 0x14 - bit 4 in 'ContainerValue'.
|
||||
_ [5]byte // 0x15
|
||||
}
|
||||
|
||||
func (g *guestPolicy) Debug() bool {
|
||||
return (g.ContainerValue & 0b00001000) != 0
|
||||
}
|
||||
|
||||
type tcbVersion struct {
|
||||
Bootloader uint8 // 0x0
|
||||
TEE uint8 // 0x10
|
||||
_ [4]byte // 0x2F
|
||||
SNP uint8 // 0x37
|
||||
Microcode uint8 // 0x3F
|
||||
}
|
||||
|
||||
func (t *tcbVersion) isVersion(expectedBootloader, expectedTEE, expectedSNP, expectedMicrocode uint8) bool {
|
||||
return t.Bootloader >= expectedBootloader && t.TEE >= expectedTEE && t.SNP >= expectedSNP && t.Microcode >= expectedMicrocode
|
||||
}
|
||||
|
||||
func (t *tcbVersion) supersededBy(new tcbVersion) bool {
|
||||
return new.Bootloader >= t.Bootloader && new.TEE >= t.TEE && new.SNP >= t.SNP && new.Microcode >= t.Microcode
|
||||
}
|
||||
|
||||
type snpSignature struct {
|
||||
R [72]byte
|
||||
S [72]byte
|
||||
Reserved [512 - 144]byte
|
||||
}
|
||||
type ecdsaSig struct {
|
||||
R, S *big.Int
|
||||
}
|
||||
|
||||
// akPub are the public parameters of an RSA attestation key.
|
||||
type akPub struct {
|
||||
E string
|
||||
N string
|
||||
|
File diff suppressed because one or more lines are too long
@ -83,7 +83,7 @@ require (
|
||||
github.com/google/gnostic v0.5.7-v3refs // indirect
|
||||
github.com/google/go-cmp v0.5.9 // indirect
|
||||
github.com/google/gofuzz v1.2.0 // indirect
|
||||
github.com/google/uuid v1.3.0 // indirect
|
||||
github.com/google/uuid v1.3.1 // indirect
|
||||
github.com/googleapis/enterprise-certificate-proxy v0.2.5 // indirect
|
||||
github.com/imdario/mergo v0.3.13 // indirect
|
||||
github.com/josharian/intern v1.0.0 // indirect
|
||||
@ -106,12 +106,12 @@ require (
|
||||
go.uber.org/atomic v1.11.0 // indirect
|
||||
go.uber.org/multierr v1.11.0 // indirect
|
||||
go.uber.org/zap v1.24.0 // indirect
|
||||
golang.org/x/crypto v0.12.0 // indirect
|
||||
golang.org/x/crypto v0.13.0 // indirect
|
||||
golang.org/x/net v0.14.0 // indirect
|
||||
golang.org/x/oauth2 v0.9.0 // indirect
|
||||
golang.org/x/sys v0.11.0 // indirect
|
||||
golang.org/x/term v0.11.0 // indirect
|
||||
golang.org/x/text v0.12.0 // indirect
|
||||
golang.org/x/sys v0.12.0 // indirect
|
||||
golang.org/x/term v0.12.0 // indirect
|
||||
golang.org/x/text v0.13.0 // indirect
|
||||
golang.org/x/time v0.3.0 // indirect
|
||||
gomodules.xyz/jsonpatch/v2 v2.3.0 // indirect
|
||||
google.golang.org/appengine v1.6.7 // indirect
|
||||
|
@ -222,8 +222,8 @@ github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm4
|
||||
github.com/google/s2a-go v0.1.4 h1:1kZ/sQM3srePvKs3tXAvQzo66XfcReoqFpIpIccE7Oc=
|
||||
github.com/google/s2a-go v0.1.4/go.mod h1:Ej+mSEMGRnqRzjc7VtF+jdBwYG5fuJfiZ8ELkjEwM0A=
|
||||
github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||
github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I=
|
||||
github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||
github.com/google/uuid v1.3.1 h1:KjJaJ9iWZ3jOFZIf1Lqf4laDRCasjl0BCmnEGxkdLb4=
|
||||
github.com/google/uuid v1.3.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||
github.com/googleapis/enterprise-certificate-proxy v0.2.5 h1:UR4rDjcgpgEnqpIEvkiqTYKBCKLNmlge2eVjoZfySzM=
|
||||
github.com/googleapis/enterprise-certificate-proxy v0.2.5/go.mod h1:RxW0N9901Cko1VOCW3SXCpWP+mlIEkk2tP7jnHy9a3w=
|
||||
github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg=
|
||||
@ -356,8 +356,8 @@ golang.org/x/crypto v0.0.0-20210421170649-83a5a9bb288b/go.mod h1:T9bdIzuCu7OtxOm
|
||||
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
|
||||
golang.org/x/crypto v0.0.0-20220314234659-1baeb1ce4c0b/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
|
||||
golang.org/x/crypto v0.0.0-20220722155217-630584e8d5aa/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
|
||||
golang.org/x/crypto v0.12.0 h1:tFM/ta59kqch6LlvYnPa0yx5a83cL2nHflFhYKvv9Yk=
|
||||
golang.org/x/crypto v0.12.0/go.mod h1:NF0Gs7EO5K4qLn+Ylc+fih8BSTeIjAP05siRnAh98yw=
|
||||
golang.org/x/crypto v0.13.0 h1:mvySKfSWJ+UKUii46M40LOvyWfN0s2U+46/jDd0e6Ck=
|
||||
golang.org/x/crypto v0.13.0/go.mod h1:y6Z2r+Rw4iayiXXAIxJIDAJ1zMW4yaTpebo8fPOliYc=
|
||||
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
||||
golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
||||
golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8=
|
||||
@ -497,12 +497,12 @@ golang.org/x/sys v0.0.0-20210616045830-e2b7044e8c71/go.mod h1:oPkhp1MJrh7nUepCBc
|
||||
golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220908164124-27713097b956/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.11.0 h1:eG7RXZHdqOJ1i+0lgLgCpSXAp6M3LYlAo6osgSi0xOM=
|
||||
golang.org/x/sys v0.11.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.12.0 h1:CM0HF96J0hcLAwsHPJZjfdNzs0gftsLfgKt57wWHJ0o=
|
||||
golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
|
||||
golang.org/x/term v0.11.0 h1:F9tnn/DA/Im8nCwm+fX+1/eBwi4qFjRT++MhtVC4ZX0=
|
||||
golang.org/x/term v0.11.0/go.mod h1:zC9APTIj3jG3FdV/Ons+XE1riIZXG4aZ4GTHiPZJPIU=
|
||||
golang.org/x/term v0.12.0 h1:/ZfYdc3zq+q02Rv9vGqTeSItdzZTSNDmfTi0mBAuidU=
|
||||
golang.org/x/term v0.12.0/go.mod h1:owVbMEjm3cBLCHdkQu9b1opXd4ETQWc3BhuQGKgXgvU=
|
||||
golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
@ -512,8 +512,8 @@ golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
|
||||
golang.org/x/text v0.3.8/go.mod h1:E6s5w1FMmriuDzIBO73fBruAKo1PCIq6d2Q6DHfQ8WQ=
|
||||
golang.org/x/text v0.12.0 h1:k+n5B8goJNdU7hSvEtMUz3d1Q6D/XW4COJSJR6fN0mc=
|
||||
golang.org/x/text v0.12.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE=
|
||||
golang.org/x/text v0.13.0 h1:ablQoSUd0tRdKxZewP80B+BaqeKJuVhuRxj/dkrun3k=
|
||||
golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE=
|
||||
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=
|
||||
|
Loading…
Reference in New Issue
Block a user