Skip to content

Commit e211718

Browse files
authored
Add experiment-gated migration to VerifyConfidentialSpace (google#586)
1 parent ea07e0a commit e211718

File tree

4 files changed

+154
-21
lines changed

4 files changed

+154
-21
lines changed

launcher/agent/agent.go

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -251,16 +251,24 @@ func (a *agent) AttestWithClient(ctx context.Context, opts AttestAgentOpts, clie
251251
a.logger.Info("Found container image signatures: %v\n", signatures)
252252
}
253253

254-
resp, err := client.VerifyAttestation(ctx, req)
254+
resp, err := a.verify(ctx, req, client)
255255
if err != nil {
256256
return nil, err
257257
}
258+
258259
if len(resp.PartialErrs) > 0 {
259260
a.logger.Error(fmt.Sprintf("Partial errors from VerifyAttestation: %v", resp.PartialErrs))
260261
}
261262
return resp.ClaimsToken, nil
262263
}
263264

265+
func (a *agent) verify(ctx context.Context, req verifier.VerifyAttestationRequest, client verifier.Client) (*verifier.VerifyAttestationResponse, error) {
266+
if a.launchSpec.Experiments.EnableVerifyCS {
267+
return client.VerifyConfidentialSpace(ctx, req)
268+
}
269+
return client.VerifyAttestation(ctx, req)
270+
}
271+
264272
func convertOCIToContainerSignature(ociSig oci.Signature) (*verifier.ContainerSignature, error) {
265273
payload, err := ociSig.Payload()
266274
if err != nil {

launcher/agent/agent_test.go

Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import (
55
"crypto/rand"
66
"crypto/rsa"
77
"encoding/base64"
8+
"errors"
89
"fmt"
910
"math"
1011
"runtime"
@@ -18,6 +19,7 @@ import (
1819
"github.com/google/go-tpm-tools/cel"
1920
"github.com/google/go-tpm-tools/client"
2021
"github.com/google/go-tpm-tools/internal/test"
22+
"github.com/google/go-tpm-tools/launcher/internal/experiments"
2123
"github.com/google/go-tpm-tools/launcher/internal/logging"
2224
"github.com/google/go-tpm-tools/launcher/internal/signaturediscovery"
2325
"github.com/google/go-tpm-tools/launcher/spec"
@@ -638,3 +640,77 @@ func measureFakeEvents(attestAgent AttestationAgent) error {
638640
}
639641
return nil
640642
}
643+
644+
type testClient struct {
645+
verifyCSResp *verifier.VerifyAttestationResponse
646+
verifyAttResp *verifier.VerifyAttestationResponse
647+
}
648+
649+
func (t *testClient) CreateChallenge(_ context.Context) (*verifier.Challenge, error) {
650+
return nil, errors.New("unimplemented")
651+
}
652+
653+
func (t *testClient) VerifyAttestation(_ context.Context, _ verifier.VerifyAttestationRequest) (*verifier.VerifyAttestationResponse, error) {
654+
return t.verifyAttResp, nil
655+
}
656+
657+
func (t *testClient) VerifyConfidentialSpace(_ context.Context, _ verifier.VerifyAttestationRequest) (*verifier.VerifyAttestationResponse, error) {
658+
return t.verifyCSResp, nil
659+
}
660+
661+
func TestVerify(t *testing.T) {
662+
expectedCSResp := &verifier.VerifyAttestationResponse{
663+
ClaimsToken: []byte("verify-cs-token"),
664+
}
665+
expectedAttResp := &verifier.VerifyAttestationResponse{
666+
ClaimsToken: []byte("verify-att-token"),
667+
}
668+
669+
vClient := &testClient{
670+
verifyCSResp: expectedCSResp,
671+
verifyAttResp: expectedAttResp,
672+
}
673+
674+
testcases := []struct {
675+
name string
676+
opts AttestAgentOpts
677+
exps experiments.Experiments
678+
expectedResp *verifier.VerifyAttestationResponse
679+
}{
680+
{
681+
name: "VerifyCS in experiment",
682+
exps: experiments.Experiments{
683+
EnableVerifyCS: true,
684+
},
685+
expectedResp: expectedCSResp,
686+
},
687+
{
688+
name: "VerifyAtt in experiment",
689+
exps: experiments.Experiments{
690+
EnableVerifyCS: false,
691+
},
692+
expectedResp: expectedAttResp,
693+
},
694+
}
695+
696+
ctx := context.Background()
697+
698+
for _, tc := range testcases {
699+
t.Run(tc.name, func(t *testing.T) {
700+
attAgent := agent{
701+
launchSpec: spec.LaunchSpec{
702+
Experiments: tc.exps,
703+
},
704+
}
705+
706+
resp, err := attAgent.verify(ctx, verifier.VerifyAttestationRequest{}, vClient)
707+
if err != nil {
708+
t.Fatalf("verify() returned failure: %v", err)
709+
}
710+
711+
if diff := cmp.Diff(resp, tc.expectedResp); diff != "" {
712+
t.Errorf("verify() did not return expected response (-got, +want): %v", diff)
713+
}
714+
})
715+
}
716+
}

launcher/teeserver/tee_server_test.go

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -507,3 +507,72 @@ func TestCustomTokenDataParsedSuccessfully(t *testing.T) {
507507
}
508508
}
509509
}
510+
511+
func TestCustomHandleAttestError(t *testing.T) {
512+
body := `{
513+
"audience": "audience",
514+
"nonces": ["thisIsAcustomNonce"],
515+
"token_type": "OIDC"
516+
}`
517+
518+
testcases := []struct {
519+
name string
520+
err error
521+
wantStatusCode int
522+
}{
523+
{
524+
name: "FailedPrecondition error",
525+
err: status.New(codes.FailedPrecondition, "bad state").Err(),
526+
wantStatusCode: http.StatusBadRequest,
527+
},
528+
{
529+
name: "PermissionDenied error",
530+
err: status.New(codes.PermissionDenied, "denied").Err(),
531+
wantStatusCode: http.StatusBadRequest,
532+
},
533+
{
534+
name: "Internal error",
535+
err: status.New(codes.Internal, "internal server error").Err(),
536+
wantStatusCode: http.StatusInternalServerError,
537+
},
538+
{
539+
name: "Unavailable error",
540+
err: status.New(codes.Unavailable, "service unavailable").Err(),
541+
wantStatusCode: http.StatusInternalServerError,
542+
},
543+
{
544+
name: "non-gRPC error",
545+
err: errors.New("a generic error"),
546+
wantStatusCode: http.StatusInternalServerError,
547+
},
548+
}
549+
for _, tc := range testcases {
550+
t.Run(tc.name, func(t *testing.T) {
551+
ah := attestHandler{
552+
logger: logging.SimpleLogger(),
553+
clients: AttestClients{
554+
GCA: &fakeVerifierClient{},
555+
},
556+
attestAgent: fakeAttestationAgent{
557+
attestWithClientFunc: func(context.Context, agent.AttestAgentOpts, verifier.Client) ([]byte, error) {
558+
return nil, tc.err
559+
},
560+
},
561+
}
562+
563+
req := httptest.NewRequest(http.MethodPost, "/v1/token", strings.NewReader(body))
564+
w := httptest.NewRecorder()
565+
566+
ah.getToken(w, req)
567+
568+
if w.Code != tc.wantStatusCode {
569+
t.Errorf("got status code %d, want %d", w.Code, tc.wantStatusCode)
570+
}
571+
572+
_, err := io.ReadAll(w.Result().Body)
573+
if err != nil {
574+
t.Errorf("failed to read response body: %v", err)
575+
}
576+
})
577+
}
578+
}

verifier/rest/rest.go

Lines changed: 0 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,6 @@ import (
1414
tpb "github.com/google/go-tdx-guest/proto/tdx"
1515
"github.com/google/go-tpm-tools/verifier"
1616
"github.com/google/go-tpm-tools/verifier/models"
17-
"github.com/google/go-tpm-tools/verifier/oci"
1817
"github.com/googleapis/gax-go/v2"
1918

2019
v1 "cloud.google.com/go/confidentialcomputing/apiv1"
@@ -301,25 +300,6 @@ func convertResponseFromREST(resp *ccpb.VerifyAttestationResponse) (*verifier.Ve
301300
}, nil
302301
}
303302

304-
func convertOCISignatureToREST(signature oci.Signature) (*ccpb.ContainerImageSignature, error) {
305-
payload, err := signature.Payload()
306-
if err != nil {
307-
return nil, err
308-
}
309-
b64Sig, err := signature.Base64Encoded()
310-
if err != nil {
311-
return nil, err
312-
}
313-
sigBytes, err := encoding.DecodeString(b64Sig)
314-
if err != nil {
315-
return nil, err
316-
}
317-
return &ccpb.ContainerImageSignature{
318-
Payload: payload,
319-
Signature: sigBytes,
320-
}, nil
321-
}
322-
323303
func convertSEVSNPProtoToREST(att *spb.Attestation) (*ccpb.VerifyAttestationRequest_SevSnpAttestation, error) {
324304
auxBlob := sabi.CertsFromProto(att.GetCertificateChain()).Marshal()
325305
rawReport, err := sabi.ReportToAbiBytes(att.GetReport())

0 commit comments

Comments
 (0)