Skip to content

Commit d2379fa

Browse files
authored
remove Attested COS specific CEL parsing logic (#597)
1 parent 9a1d2ad commit d2379fa

File tree

3 files changed

+38
-170
lines changed

3 files changed

+38
-170
lines changed

server/verify.go

Lines changed: 0 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,6 @@ import (
88
"errors"
99
"fmt"
1010

11-
"github.com/google/go-eventlog/proto/state"
12-
"github.com/google/go-eventlog/register"
1311
"github.com/google/go-tpm-tools/internal"
1412
pb "github.com/google/go-tpm-tools/proto/attest"
1513
tpmpb "github.com/google/go-tpm-tools/proto/tpm"
@@ -138,26 +136,6 @@ func VerifyAttestation(attestation *pb.Attestation, opts VerifyOpts) (*pb.Machin
138136
continue
139137
}
140138

141-
pcrBank := register.PCRBank{TCGHashAlgo: state.HashAlgo(pcrs.Hash)}
142-
digestAlg, err := pcrBank.TCGHashAlgo.CryptoHash()
143-
if err != nil {
144-
return nil, fmt.Errorf("invalid digest algorithm")
145-
}
146-
147-
for pcrIndex, digest := range pcrs.GetPcrs() {
148-
pcrBank.PCRs = append(pcrBank.PCRs, register.PCR{
149-
Index: int(pcrIndex),
150-
Digest: digest,
151-
DigestAlg: digestAlg})
152-
}
153-
154-
celState, err := ParseCosCELPCR(attestation.GetCanonicalEventLog(), pcrBank)
155-
if err != nil {
156-
lastErr = fmt.Errorf("failed to validate the Canonical event log: %w", err)
157-
continue
158-
}
159-
machineState.Cos = celState
160-
161139
// Verify the PCR hash algorithm. We have this check here (instead of at
162140
// the start of the loop) so that the user gets a "SHA-1 not supported"
163141
// error only if allowing SHA-1 support would actually allow the log

server/verify_test.go

Lines changed: 0 additions & 148 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
package server
22

33
import (
4-
"bytes"
54
"crypto"
65
"crypto/rand"
76
"crypto/rsa"
@@ -14,11 +13,8 @@ import (
1413
"fmt"
1514
"io"
1615
"os"
17-
"strings"
1816
"testing"
1917

20-
"github.com/google/go-cmp/cmp"
21-
"github.com/google/go-tpm-tools/cel"
2218
"github.com/google/go-tpm-tools/client"
2319
"github.com/google/go-tpm-tools/internal"
2420
"github.com/google/go-tpm-tools/internal/test"
@@ -27,7 +23,6 @@ import (
2723
"github.com/google/go-tpm/tpmutil"
2824
"github.com/google/logger"
2925
"google.golang.org/protobuf/proto"
30-
"google.golang.org/protobuf/testing/protocmp"
3126
)
3227

3328
func getDigestHash(input string) []byte {
@@ -278,149 +273,6 @@ func TestVerifySHA1Attestation(t *testing.T) {
278273
}
279274
}
280275

281-
func TestVerifyAttestationWithCEL(t *testing.T) {
282-
test.SkipForRealTPM(t)
283-
rwc := test.GetTPM(t)
284-
defer client.CheckedClose(t, rwc)
285-
286-
ak, err := client.AttestationKeyRSA(rwc)
287-
if err != nil {
288-
t.Fatalf("failed to generate AK: %v", err)
289-
}
290-
defer ak.Close()
291-
292-
coscel := &cel.CEL{}
293-
testEvents := []struct {
294-
cosNestedEventType cel.CosType
295-
pcr int
296-
eventPayload []byte
297-
}{
298-
{cel.ImageRefType, cel.CosEventPCR, []byte("docker.io/bazel/experimental/test:latest")},
299-
{cel.ImageDigestType, cel.CosEventPCR, []byte("sha256:781d8dfdd92118436bd914442c8339e653b83f6bf3c1a7a98efcfb7c4fed7483")},
300-
{cel.RestartPolicyType, cel.CosEventPCR, []byte(attestpb.RestartPolicy_Never.String())},
301-
{cel.ImageIDType, cel.CosEventPCR, []byte("sha256:5DF4A1AC347DCF8CF5E9D0ABC04B04DB847D1B88D3B1CC1006F0ACB68E5A1F4B")},
302-
{cel.EnvVarType, cel.CosEventPCR, []byte("foo=bar")},
303-
{cel.EnvVarType, cel.CosEventPCR, []byte("bar=baz")},
304-
{cel.EnvVarType, cel.CosEventPCR, []byte("baz=foo=bar")},
305-
{cel.EnvVarType, cel.CosEventPCR, []byte("empty=")},
306-
{cel.ArgType, cel.CosEventPCR, []byte("--x")},
307-
{cel.ArgType, cel.CosEventPCR, []byte("--y")},
308-
{cel.OverrideArgType, cel.CosEventPCR, []byte("--x")},
309-
{cel.OverrideEnvType, cel.CosEventPCR, []byte("empty=")},
310-
{cel.MemoryMonitorType, cel.CosEventPCR, []byte{1}},
311-
}
312-
for _, testEvent := range testEvents {
313-
cosEvent := cel.CosTlv{EventType: testEvent.cosNestedEventType, EventContent: testEvent.eventPayload}
314-
if err := coscel.AppendEventPCR(rwc, testEvent.pcr, cosEvent); err != nil {
315-
t.Fatal(err)
316-
}
317-
}
318-
319-
var buf bytes.Buffer
320-
if err := coscel.EncodeCEL(&buf); err != nil {
321-
t.Fatal(err)
322-
}
323-
324-
nonce := []byte("super secret nonce")
325-
attestation, err := ak.Attest(client.AttestOpts{Nonce: nonce, CanonicalEventLog: buf.Bytes()})
326-
if err != nil {
327-
t.Fatalf("failed to attest: %v", err)
328-
}
329-
330-
opts := VerifyOpts{
331-
Nonce: nonce,
332-
TrustedAKs: []crypto.PublicKey{ak.PublicKey()},
333-
}
334-
state, err := VerifyAttestation(attestation, opts)
335-
if err != nil {
336-
t.Fatalf("failed to verify: %v", err)
337-
}
338-
339-
expectedEnvVars := make(map[string]string)
340-
expectedEnvVars["foo"] = "bar"
341-
expectedEnvVars["bar"] = "baz"
342-
expectedEnvVars["baz"] = "foo=bar"
343-
expectedEnvVars["empty"] = ""
344-
345-
expectedOverriddenEnvVars := make(map[string]string)
346-
expectedOverriddenEnvVars["empty"] = ""
347-
348-
wantContainerState := attestpb.ContainerState{
349-
ImageReference: string(testEvents[0].eventPayload),
350-
ImageDigest: string(testEvents[1].eventPayload),
351-
RestartPolicy: attestpb.RestartPolicy_Never,
352-
ImageId: string(testEvents[3].eventPayload),
353-
EnvVars: expectedEnvVars,
354-
Args: []string{string(testEvents[8].eventPayload), string(testEvents[9].eventPayload)},
355-
OverriddenEnvVars: expectedOverriddenEnvVars,
356-
OverriddenArgs: []string{string(testEvents[10].eventPayload)},
357-
}
358-
enabled := true
359-
wantHealthMonitoringState := attestpb.HealthMonitoringState{
360-
MemoryEnabled: &enabled,
361-
}
362-
if diff := cmp.Diff(state.Cos.Container, &wantContainerState, protocmp.Transform()); diff != "" {
363-
t.Errorf("unexpected container state difference:\n%v", diff)
364-
}
365-
if diff := cmp.Diff(state.Cos.HealthMonitoring, &wantHealthMonitoringState, protocmp.Transform()); diff != "" {
366-
t.Errorf("unexpected health monitoring state difference:\n%v", diff)
367-
}
368-
}
369-
370-
func TestVerifyFailWithTamperedCELContent(t *testing.T) {
371-
test.SkipForRealTPM(t)
372-
rwc := test.GetTPM(t)
373-
defer client.CheckedClose(t, rwc)
374-
375-
ak, err := client.AttestationKeyRSA(rwc)
376-
if err != nil {
377-
t.Fatalf("failed to generate AK: %v", err)
378-
}
379-
defer ak.Close()
380-
381-
c := &cel.CEL{}
382-
383-
cosEvent := cel.CosTlv{EventType: cel.ImageRefType, EventContent: []byte("docker.io/bazel/experimental/test:latest")}
384-
cosEvent2 := cel.CosTlv{EventType: cel.ImageDigestType, EventContent: []byte("sha256:781d8dfdd92118436bd914442c8339e653b83f6bf3c1a7a98efcfb7c4fed7483")}
385-
386-
if err := c.AppendEventPCR(rwc, cel.CosEventPCR, cosEvent); err != nil {
387-
t.Fatalf("failed to append event: %v", err)
388-
}
389-
390-
if err := c.AppendEventPCR(rwc, cel.CosEventPCR, cosEvent2); err != nil {
391-
t.Fatalf("failed to append event: %v", err)
392-
}
393-
394-
// modify the first record content, but not the record digest
395-
modifiedRecord := cel.CosTlv{EventType: cel.ImageDigestType, EventContent: []byte("sha256:000000000000000000000000000000000000000000000000000000000000000")}
396-
modifiedTLV, err := modifiedRecord.GetTLV()
397-
if err != nil {
398-
t.Fatal(err)
399-
}
400-
c.Records[0].Content = modifiedTLV
401-
402-
var buf bytes.Buffer
403-
if err := c.EncodeCEL(&buf); err != nil {
404-
t.Fatal(err)
405-
}
406-
407-
nonce := []byte("super secret nonce")
408-
attestation, err := ak.Attest(client.AttestOpts{Nonce: nonce, CanonicalEventLog: buf.Bytes()})
409-
if err != nil {
410-
t.Fatalf("failed to attest: %v", err)
411-
}
412-
413-
opts := VerifyOpts{
414-
Nonce: nonce,
415-
TrustedAKs: []crypto.PublicKey{ak.PublicKey()},
416-
}
417-
if _, err := VerifyAttestation(attestation, opts); err == nil {
418-
t.Fatalf("VerifyAttestation should fail due to modified content")
419-
} else if !strings.Contains(err.Error(), "CEL record content digest verification failed") {
420-
t.Fatalf("expect to get digest verification failed error, but got %v", err)
421-
}
422-
}
423-
424276
func TestVerifyAttestationWithCerts(t *testing.T) {
425277
tests := []struct {
426278
name string

verifier/fake/fakeverifier.go

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,10 @@ import (
1111
"time"
1212

1313
"github.com/golang-jwt/jwt/v4"
14+
"github.com/google/go-eventlog/proto/state"
15+
"github.com/google/go-eventlog/register"
16+
"github.com/google/go-tpm-tools/proto/attest"
17+
"github.com/google/go-tpm-tools/proto/tpm"
1418
"github.com/google/go-tpm-tools/server"
1519
"github.com/google/go-tpm-tools/verifier"
1620
"github.com/google/go-tpm-tools/verifier/oci"
@@ -63,6 +67,17 @@ func (fc *fakeClient) VerifyAttestation(_ context.Context, req verifier.VerifyAt
6367
return nil, fmt.Errorf("failed to verify attestation: %v", err)
6468
}
6569

70+
pcrBank, err := extractPCRBank(req.Attestation, ms.GetHash())
71+
if err != nil {
72+
return nil, fmt.Errorf("failed to extract PCR bank: %w", err)
73+
}
74+
75+
cosState, err := server.ParseCosCELPCR(req.Attestation.GetCanonicalEventLog(), *pcrBank)
76+
if err != nil {
77+
return nil, fmt.Errorf("failed to validate the Canonical event log: %w", err)
78+
}
79+
ms.Cos = cosState
80+
6681
msJSON, err := protojson.Marshal(ms)
6782
if err != nil {
6883
return nil, fmt.Errorf("failed to convert proto object to JSON: %v", err)
@@ -144,3 +159,26 @@ func extractClaims(signature *verifier.ContainerSignature) (ContainerImageSignat
144159
SigAlg: sigAlg,
145160
}, nil
146161
}
162+
163+
// extractPCRBank finds the quote matching the given hash algorithm and returns the PCR bank.
164+
func extractPCRBank(attestation *attest.Attestation, hashAlgo tpm.HashAlgo) (*register.PCRBank, error) {
165+
for _, quote := range attestation.GetQuotes() {
166+
pcrs := quote.GetPcrs()
167+
if pcrs.GetHash() == hashAlgo {
168+
pcrBank := &register.PCRBank{TCGHashAlgo: state.HashAlgo(pcrs.Hash)}
169+
digestAlg, err := pcrBank.TCGHashAlgo.CryptoHash()
170+
if err != nil {
171+
return nil, fmt.Errorf("invalid digest algorithm: %w", err)
172+
}
173+
174+
for pcrIndex, digest := range pcrs.GetPcrs() {
175+
pcrBank.PCRs = append(pcrBank.PCRs, register.PCR{
176+
Index: int(pcrIndex),
177+
Digest: digest,
178+
DigestAlg: digestAlg})
179+
}
180+
return pcrBank, nil
181+
}
182+
}
183+
return nil, fmt.Errorf("no PCRs found matching hash %s", hashAlgo.String())
184+
}

0 commit comments

Comments
 (0)