mirror of
https://github.com/edgelesssys/constellation.git
synced 2024-12-26 07:59:37 -05:00
cli: print ordered measurements list during constellation verify
(#2302)
* Print measurements as ordered list during verify * Fix missing safety check in AWS attestation validation --------- Signed-off-by: Daniel Weiße <dw@edgeless.systems>
This commit is contained in:
parent
0eb9ca2e18
commit
9765003298
@ -160,6 +160,7 @@ go_test(
|
|||||||
"//internal/versions",
|
"//internal/versions",
|
||||||
"//operators/constellation-node-operator/api/v1alpha1",
|
"//operators/constellation-node-operator/api/v1alpha1",
|
||||||
"//verify/verifyproto",
|
"//verify/verifyproto",
|
||||||
|
"@com_github_google_go_tpm_tools//proto/tpm",
|
||||||
"@com_github_spf13_afero//:afero",
|
"@com_github_spf13_afero//:afero",
|
||||||
"@com_github_spf13_cobra//:cobra",
|
"@com_github_spf13_cobra//:cobra",
|
||||||
"@com_github_stretchr_testify//assert",
|
"@com_github_stretchr_testify//assert",
|
||||||
|
@ -19,6 +19,7 @@ import (
|
|||||||
"net"
|
"net"
|
||||||
"net/http"
|
"net/http"
|
||||||
"net/url"
|
"net/url"
|
||||||
|
"sort"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
@ -381,19 +382,23 @@ func (f *attestationDocFormatterImpl) parseCerts(b *strings.Builder, certTypeNam
|
|||||||
// parseQuotes parses the base64-encoded quotes and writes their details to the output builder.
|
// parseQuotes parses the base64-encoded quotes and writes their details to the output builder.
|
||||||
func (f *attestationDocFormatterImpl) parseQuotes(b *strings.Builder, quotes []*tpmProto.Quote, expectedPCRs measurements.M) error {
|
func (f *attestationDocFormatterImpl) parseQuotes(b *strings.Builder, quotes []*tpmProto.Quote, expectedPCRs measurements.M) error {
|
||||||
writeIndentfln(b, 1, "Quote:")
|
writeIndentfln(b, 1, "Quote:")
|
||||||
for pcrNum, expectedPCR := range expectedPCRs {
|
|
||||||
|
var pcrNumbers []uint32
|
||||||
|
for pcrNum := range expectedPCRs {
|
||||||
|
pcrNumbers = append(pcrNumbers, pcrNum)
|
||||||
|
}
|
||||||
|
sort.Slice(pcrNumbers, func(i, j int) bool { return pcrNumbers[i] < pcrNumbers[j] })
|
||||||
|
|
||||||
|
for _, pcrNum := range pcrNumbers {
|
||||||
|
expectedPCR := expectedPCRs[pcrNum]
|
||||||
pcrIdx, err := vtpm.GetSHA256QuoteIndex(quotes)
|
pcrIdx, err := vtpm.GetSHA256QuoteIndex(quotes)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("get SHA256 quote index: %w", err)
|
return fmt.Errorf("get SHA256 quote index: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
if quotes[pcrIdx] == nil {
|
actualPCR, ok := quotes[pcrIdx].Pcrs.Pcrs[pcrNum]
|
||||||
return fmt.Errorf("quote %d is nil", pcrIdx)
|
if !ok {
|
||||||
}
|
return fmt.Errorf("PCR %d not found in quote", pcrNum)
|
||||||
|
|
||||||
actualPCR := quotes[pcrIdx].Pcrs.Pcrs[pcrNum]
|
|
||||||
if err != nil {
|
|
||||||
return fmt.Errorf("decode PCR %d: %w", pcrNum, err)
|
|
||||||
}
|
}
|
||||||
writeIndentfln(b, 2, "PCR %d (Strict: %t):", pcrNum, !expectedPCR.ValidationOpt)
|
writeIndentfln(b, 2, "PCR %d (Strict: %t):", pcrNum, !expectedPCR.ValidationOpt)
|
||||||
writeIndentfln(b, 3, "Expected:\t%x", expectedPCR.Expected)
|
writeIndentfln(b, 3, "Expected:\t%x", expectedPCR.Expected)
|
||||||
|
@ -29,6 +29,7 @@ import (
|
|||||||
"github.com/edgelesssys/constellation/v2/internal/grpc/testdialer"
|
"github.com/edgelesssys/constellation/v2/internal/grpc/testdialer"
|
||||||
"github.com/edgelesssys/constellation/v2/internal/logger"
|
"github.com/edgelesssys/constellation/v2/internal/logger"
|
||||||
"github.com/edgelesssys/constellation/v2/verify/verifyproto"
|
"github.com/edgelesssys/constellation/v2/verify/verifyproto"
|
||||||
|
tpmProto "github.com/google/go-tpm-tools/proto/tpm"
|
||||||
"github.com/spf13/afero"
|
"github.com/spf13/afero"
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
"github.com/stretchr/testify/require"
|
"github.com/stretchr/testify/require"
|
||||||
@ -466,3 +467,93 @@ func TestAddPortIfMissing(t *testing.T) {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestParseQuotes(t *testing.T) {
|
||||||
|
testCases := map[string]struct {
|
||||||
|
quotes []*tpmProto.Quote
|
||||||
|
expectedPCRs measurements.M
|
||||||
|
wantOutput string
|
||||||
|
wantErr bool
|
||||||
|
}{
|
||||||
|
"parse quotes in order": {
|
||||||
|
quotes: []*tpmProto.Quote{
|
||||||
|
{
|
||||||
|
Pcrs: &tpmProto.PCRs{
|
||||||
|
Hash: tpmProto.HashAlgo_SHA256,
|
||||||
|
Pcrs: map[uint32][]byte{
|
||||||
|
0: {0x00},
|
||||||
|
1: {0x01},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
expectedPCRs: measurements.M{
|
||||||
|
0: measurements.WithAllBytes(0x00, measurements.Enforce, 1),
|
||||||
|
1: measurements.WithAllBytes(0x01, measurements.WarnOnly, 1),
|
||||||
|
},
|
||||||
|
wantOutput: "\tQuote:\n\t\tPCR 0 (Strict: true):\n\t\t\tExpected:\t00\n\t\t\tActual:\t\t00\n\t\tPCR 1 (Strict: false):\n\t\t\tExpected:\t01\n\t\t\tActual:\t\t01\n",
|
||||||
|
},
|
||||||
|
"additional quotes are skipped": {
|
||||||
|
quotes: []*tpmProto.Quote{
|
||||||
|
{
|
||||||
|
Pcrs: &tpmProto.PCRs{
|
||||||
|
Hash: tpmProto.HashAlgo_SHA256,
|
||||||
|
Pcrs: map[uint32][]byte{
|
||||||
|
0: {0x00},
|
||||||
|
1: {0x01},
|
||||||
|
2: {0x02},
|
||||||
|
3: {0x03},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
expectedPCRs: measurements.M{
|
||||||
|
0: measurements.WithAllBytes(0x00, measurements.Enforce, 1),
|
||||||
|
1: measurements.WithAllBytes(0x01, measurements.WarnOnly, 1),
|
||||||
|
},
|
||||||
|
wantOutput: "\tQuote:\n\t\tPCR 0 (Strict: true):\n\t\t\tExpected:\t00\n\t\t\tActual:\t\t00\n\t\tPCR 1 (Strict: false):\n\t\t\tExpected:\t01\n\t\t\tActual:\t\t01\n",
|
||||||
|
},
|
||||||
|
"missing quotes error": {
|
||||||
|
quotes: []*tpmProto.Quote{
|
||||||
|
{
|
||||||
|
Pcrs: &tpmProto.PCRs{
|
||||||
|
Hash: tpmProto.HashAlgo_SHA256,
|
||||||
|
Pcrs: map[uint32][]byte{
|
||||||
|
0: {0x00},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
expectedPCRs: measurements.M{
|
||||||
|
0: measurements.WithAllBytes(0x00, measurements.Enforce, 1),
|
||||||
|
1: measurements.WithAllBytes(0x01, measurements.WarnOnly, 1),
|
||||||
|
},
|
||||||
|
wantErr: true,
|
||||||
|
},
|
||||||
|
"no quotes error": {
|
||||||
|
quotes: []*tpmProto.Quote{},
|
||||||
|
expectedPCRs: measurements.M{
|
||||||
|
0: measurements.WithAllBytes(0x00, measurements.Enforce, 1),
|
||||||
|
1: measurements.WithAllBytes(0x01, measurements.WarnOnly, 1),
|
||||||
|
},
|
||||||
|
wantErr: true,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
for name, tc := range testCases {
|
||||||
|
t.Run(name, func(t *testing.T) {
|
||||||
|
assert := assert.New(t)
|
||||||
|
|
||||||
|
b := &strings.Builder{}
|
||||||
|
parser := &attestationDocFormatterImpl{}
|
||||||
|
|
||||||
|
err := parser.parseQuotes(b, tc.quotes, tc.expectedPCRs)
|
||||||
|
if tc.wantErr {
|
||||||
|
assert.Error(err)
|
||||||
|
} else {
|
||||||
|
assert.NoError(err)
|
||||||
|
assert.Equal(tc.wantOutput, b.String())
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -80,12 +80,18 @@ func (v *Validator) tpmEnabled(attestation vtpm.AttestationDocument, _ *attest.M
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
if len(imageOutput.Images) == 0 {
|
||||||
|
return fmt.Errorf("aws image %s not found", imageID)
|
||||||
|
}
|
||||||
|
if len(imageOutput.Images) > 1 {
|
||||||
|
return fmt.Errorf("found multiple image references for image ID %s", imageID)
|
||||||
|
}
|
||||||
|
|
||||||
if imageOutput.Images[0].TpmSupport == "v2.0" {
|
if imageOutput.Images[0].TpmSupport == "v2.0" {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
return fmt.Errorf("iam image %s does not support TPM v2.0", imageID)
|
return fmt.Errorf("aws image %s does not support TPM v2.0", imageID)
|
||||||
}
|
}
|
||||||
|
|
||||||
func getEC2Client(ctx context.Context, region string) (awsMetadataAPI, error) {
|
func getEC2Client(ctx context.Context, region string) (awsMetadataAPI, error) {
|
||||||
|
Loading…
Reference in New Issue
Block a user