Skip to content

Commit

Permalink
Add fake client for launcher/verifier/client interface
Browse files Browse the repository at this point in the history
Fix test with new Fake Client
  • Loading branch information
Josh Krstic committed Aug 4, 2022
1 parent 51031c1 commit 02aca36
Show file tree
Hide file tree
Showing 5 changed files with 89 additions and 31 deletions.
2 changes: 1 addition & 1 deletion launcher/agent/agent.go
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ func (a *agent) MeasureEvent(event cel.Content) error {

// Attest fetches the nonce and connection ID from the Attestation Service,
// creates an attestation message, and returns the resultant
// principalIDTokens are Metadata Server-generated ID tokens for the instance.
// principalIDTokens and Metadata Server-generated ID tokens for the instance.
func (a *agent) Attest(ctx context.Context) ([]byte, error) {
challenge, err := a.client.CreateChallenge(ctx)
if err != nil {
Expand Down
52 changes: 28 additions & 24 deletions launcher/agent/agent_test.go
Original file line number Diff line number Diff line change
@@ -1,19 +1,18 @@
package agent

import (
"bytes"
"context"
"log"
"net"
"crypto/rand"
"crypto/rsa"
"fmt"
"testing"

"github.com/golang-jwt/jwt/v4"
"github.com/google/go-tpm-tools/client"
"github.com/google/go-tpm-tools/internal/test"
"github.com/google/go-tpm-tools/launcher/verifier/grpcclient"
"github.com/google/go-tpm-tools/launcher/verifier/fake"
"github.com/google/go-tpm-tools/launcher/verifier/grpcclient/service"
"google.golang.org/grpc"
"google.golang.org/grpc/credentials/insecure"
"google.golang.org/grpc/test/bufconn"

servgrpc "github.com/google/go-tpm-tools/launcher/verifier/grpcclient/proto/attestation_verifier/v0"
)
Expand All @@ -27,32 +26,37 @@ func TestAttest(t *testing.T) {
fakeServer := service.New()
servgrpc.RegisterAttestationVerifierServer(server, &fakeServer)

lis := bufconn.Listen(1024 * 1024)
go func() {
if err := server.Serve(lis); err != nil {
log.Fatalf("Server exited with error: %v", err)
}
}()
bufDialer := func(context.Context, string) (net.Conn, error) {
return lis.Dial()
}
fakeSigner, _ := rsa.GenerateKey(rand.Reader, 2048)
verifierClient := fake.NewClient(fakeSigner)
agent := CreateAttestationAgent(tpm, client.AttestationKeyECC, verifierClient, placeholderFetcher)

conn, err := grpc.DialContext(context.Background(), "bufconn", grpc.WithContextDialer(bufDialer), grpc.WithTransportCredentials(insecure.NewCredentials()))
tokenBytes, err := agent.Attest(context.Background())
if err != nil {
t.Fatalf("failed to connect to attestation service: %v", err)
t.Errorf("failed to attest to Attestation Service: %v", err)
}
verifierClient := grpcclient.NewClient(conn, log.Default())
// Cannot test a GCE key on the simulator.
agent := CreateAttestationAgent(tpm, client.AttestationKeyECC, verifierClient, placeholderFetcher)

token, err := agent.Attest(context.Background())
registeredClaims := &jwt.RegisteredClaims{}
keyFunc := func(token *jwt.Token) (interface{}, error) { return fakeSigner.Public(), nil }
token, err := jwt.ParseWithClaims(string(tokenBytes), registeredClaims, keyFunc)

err = registeredClaims.Valid()
if err != nil {
t.Errorf("failed to attest to Attestation Service: %v", err)
t.Errorf("Invalid exp, iat, or nbf: %s", err)
}

if !bytes.Equal(token, service.FakeToken) {
t.Errorf("received unexpected token: %v, expected: %v", token, service.FakeToken)
if !registeredClaims.VerifyAudience("TestingAudience", true) {
t.Errorf("Invalid aud")
}

if !registeredClaims.VerifyIssuer("TestingIssuer", true) {
t.Errorf("Invalid iss")
}

if registeredClaims.Subject != "TestingSubject" {
t.Errorf("Invalid sub")
}

fmt.Printf("token.Claims: %v\n", token.Claims)
}

func placeholderFetcher(audience string) ([][]byte, error) {
Expand Down
59 changes: 59 additions & 0 deletions launcher/verifier/fake/fakeverifier.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
// Package fakeverifier is a fake implementation of the AttestationVerifier for testing.
package fake

import (
"context"
"crypto"

"github.com/golang-jwt/jwt/v4"
"github.com/google/go-tpm-tools/launcher/verifier"
)

type fakeClient struct {
//pbClient servpb.AttestationVerifierClient
signer crypto.Signer
}

func NewClient(signer crypto.Signer) verifier.Client {
return &fakeClient{signer}
}

// CreateChallenge returns a hard coded, basic challenge.
//
// If you have found this method is insufficient for your tests, this class must be updated to
// allow for better testing.
func (fc *fakeClient) CreateChallenge(ctx context.Context) (*verifier.Challenge, error) {
return &verifier.Challenge{
Name: "FakeName",
Nonce: []byte{0x0},
}, nil
}

// VerifyAttestation does basic checks and returns a hard coded attestation response.
//
// If you have found this method is insufficient for your tests, this class must be updated to
// allow for better testing.
func (fc *fakeClient) VerifyAttestation(ctx context.Context, request verifier.VerifyAttestationRequest) (*verifier.VerifyAttestationResponse, error) {
// Determine signing algorithm.
signingMethod := jwt.SigningMethodRS256
now := jwt.TimeFunc()
claims := jwt.RegisteredClaims{
IssuedAt: &jwt.NumericDate{Time: now},
NotBefore: &jwt.NumericDate{Time: now},
ExpiresAt: &jwt.NumericDate{Time: now.Add(60 * 60 * 1e9)}, // Add takes nanoseconds
Audience: []string{"TestingAudience"},
Issuer: "TestingIssuer",
Subject: "TestingSubject",
}

token := jwt.NewWithClaims(signingMethod, claims)

// Instead of a private key, provide the signer.
signed, _ := token.SignedString(fc.signer)

response := verifier.VerifyAttestationResponse{
ClaimsToken: []byte(signed),
}

return &response, nil
}
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,6 @@ import (
_ "embed"
)

// FakeToken is generated by fake_tokens/fake_rsa_token.txt.
//go:embed fake_tokens/fake_rsa_token.txt
var FakeToken []byte

// FakeServer implements the AttestationVerifier service methods. The initial
// connection ID produced by the server will be "0", incrementing with every
// subsequent request to GetParams.
Expand Down Expand Up @@ -74,7 +70,7 @@ func (s *FakeServer) Verify(ctx context.Context, req *servpb.VerifyRequest) (*se

// TODO(b/210015375): Return a more realistic fake OIDC token with fake signing key and claims.
resp := &servpb.VerifyResponse{
ClaimsToken: FakeToken,
ClaimsToken: []byte{1},
}

return resp, nil
Expand Down

This file was deleted.

0 comments on commit 02aca36

Please sign in to comment.