Skip to content

Commit

Permalink
attestation: clear certificate cache in azure snp
Browse files Browse the repository at this point in the history
The unittest was flacky as testcases with valid certs
in the getter property lead to those certs being cached
inside the trust module. Other testcases however,
may want to explicitly use invalid certs. The cache
interferes with this.

Co-authored-by: Moritz Sanft <[email protected]>
  • Loading branch information
derpsteb and msanft committed Nov 8, 2023
1 parent 45df17d commit 8341db3
Show file tree
Hide file tree
Showing 2 changed files with 24 additions and 17 deletions.
1 change: 1 addition & 0 deletions internal/attestation/azure/snp/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ go_test(
"@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",
Expand Down
40 changes: 23 additions & 17 deletions internal/attestation/azure/snp/validator_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ import (
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/client"
"github.com/google/go-tpm-tools/proto/attest"
"github.com/google/go-tpm/legacy/tpm2"
Expand Down Expand Up @@ -284,6 +285,9 @@ func TestInstanceInfoAttestation(t *testing.T) {
assert := assert.New(t)
require := require.New(t)

// This is important. Without this call, the trust module caches certificates across testcases.
defer trust.ClearProductCertCache()

instanceInfo := azureInstanceInfo{
AttestationReport: tc.report,
CertChain: tc.certChain,
Expand Down Expand Up @@ -564,22 +568,21 @@ func TestTrustedKeyFromSNP(t *testing.T) {
if cgo == "0" {
t.Skip("skipping test because CGO is disabled and tpm simulator requires it")
}
require := require.New(t)

tpm, err := simulator.OpenSimulatedTPM()
require.NoError(err)
require.NoError(t, err)
defer tpm.Close()
key, err := client.AttestationKeyRSA(tpm)
require.NoError(err)
require.NoError(t, err)
defer key.Close()
akPub, err := key.PublicArea().Encode()
require.NoError(err)
require.NoError(t, err)

defaultCfg := config.DefaultForAzureSEVSNP()
defaultReport := hex.EncodeToString(testdata.AttestationReport)
defaultRuntimeData := hex.EncodeToString(testdata.RuntimeData)
defaultIDKeyDigestOld, err := hex.DecodeString("57e229e0ffe5fa92d0faddff6cae0e61c926fc9ef9afd20a8b8cfcf7129db9338cbe5bf3f6987733a2bf65d06dc38fc1")
require.NoError(err)
require.NoError(t, err)
defaultIDKeyDigest := idkeydigest.NewList([][]byte{defaultIDKeyDigestOld})
defaultVerifier := &stubAttestationVerifier{}
skipVerifier := &stubAttestationVerifier{skipCheck: true}
Expand All @@ -588,12 +591,12 @@ func TestTrustedKeyFromSNP(t *testing.T) {
// reportTransformer unpacks the hex-encoded report, applies the given transformations and re-encodes it.
reportTransformer := func(reportHex string, transformations func(*spb.Report)) string {
rawReport, err := hex.DecodeString(reportHex)
require.NoError(err)
require.NoError(t, err)
report, err := abi.ReportToProto(rawReport)
require.NoError(err)
require.NoError(t, err)
transformations(report)
reportBytes, err := abi.ReportToAbiBytes(report)
require.NoError(err)
require.NoError(t, err)
return hex.EncodeToString(reportBytes)
}

Expand Down Expand Up @@ -746,6 +749,7 @@ func TestTrustedKeyFromSNP(t *testing.T) {
},
nil,
),
wantErr: true,
},
"invalid runtime data": {
report: defaultReport,
Expand Down Expand Up @@ -821,7 +825,7 @@ func TestTrustedKeyFromSNP(t *testing.T) {
defaultCfg.MicrocodeVersion.Value = 10
launchTcb.UcodeSpl = 9
newLaunchTcb, err := kds.ComposeTCBParts(launchTcb)
require.NoError(err)
require.NoError(t, err)
r.LaunchTcb = uint64(newLaunchTcb)
}),
runtimeData: defaultRuntimeData,
Expand All @@ -845,7 +849,7 @@ func TestTrustedKeyFromSNP(t *testing.T) {
reportedTcb := kds.DecomposeTCBVersion(kds.TCBVersion(r.ReportedTcb))
reportedTcb.UcodeSpl = defaultCfg.MicrocodeVersion.Value - 1
newReportedTcb, err := kds.ComposeTCBParts(reportedTcb)
require.NoError(err)
require.NoError(t, err)
r.ReportedTcb = uint64(newReportedTcb)
}),
runtimeData: defaultRuntimeData,
Expand Down Expand Up @@ -889,7 +893,7 @@ func TestTrustedKeyFromSNP(t *testing.T) {
currentTcb := kds.DecomposeTCBVersion(kds.TCBVersion(r.CurrentTcb))
currentTcb.UcodeSpl = 0x5c // testdata.AzureThimVCEK has ucode version 0x5d
newCurrentTcb, err := kds.ComposeTCBParts(currentTcb)
require.NoError(err)
require.NoError(t, err)
r.CurrentTcb = uint64(newCurrentTcb)
}),
runtimeData: defaultRuntimeData,
Expand Down Expand Up @@ -976,14 +980,16 @@ func TestTrustedKeyFromSNP(t *testing.T) {
for name, tc := range testCases {
t.Run(name, func(t *testing.T) {
assert := assert.New(t)
require := require.New(t)

// This is important. Without this call, the trust module caches certificates across testcases.
defer trust.ClearProductCertCache()

instanceInfo, err := newStubAzureInstanceInfo(tc.vcek, tc.certChain, tc.report, tc.runtimeData)
assert.NoError(err)
require.NoError(err)

statement, err := json.Marshal(instanceInfo)
if err != nil {
assert.Error(err)
}
require.NoError(err)

attDoc := vtpm.AttestationDocument{
InstanceInfo: statement,
Expand All @@ -1008,12 +1014,12 @@ func TestTrustedKeyFromSNP(t *testing.T) {

key, err := validator.getTrustedKey(context.Background(), attDoc, nil)
if tc.wantErr {
require.Error(err)
assert.Error(err)
if tc.assertion != nil {
tc.assertion(assert, err)
}
} else {
require.NoError(err)
assert.NoError(err)
assert.NotNil(key)
}
})
Expand Down

0 comments on commit 8341db3

Please sign in to comment.