@@ -10,6 +10,7 @@ import (
10
10
"net/url"
11
11
"os"
12
12
"path"
13
+ "strings"
13
14
"time"
14
15
15
16
"cloud.google.com/go/compute/metadata"
@@ -23,10 +24,13 @@ import (
23
24
"github.com/google/go-tpm-tools/client"
24
25
"github.com/google/go-tpm-tools/launcher/agent"
25
26
"github.com/google/go-tpm-tools/launcher/spec"
27
+ "github.com/google/go-tpm-tools/launcher/verifier"
26
28
"github.com/google/go-tpm-tools/launcher/verifier/grpcclient"
29
+ "github.com/google/go-tpm-tools/launcher/verifier/rest"
27
30
v1 "github.com/opencontainers/image-spec/specs-go/v1"
28
31
specs "github.com/opencontainers/runtime-spec/specs-go"
29
32
"golang.org/x/oauth2"
33
+ "golang.org/x/oauth2/google"
30
34
"google.golang.org/api/impersonate"
31
35
"google.golang.org/api/option"
32
36
"google.golang.org/grpc"
@@ -161,14 +165,6 @@ func NewRunner(ctx context.Context, cdClient *containerd.Client, token oauth2.To
161
165
return nil , fmt .Errorf ("length of Args [%d] is shorter or equal to the length of the given Cmd [%d], maybe the Entrypoint is set to empty in the image?" , len (containerSpec .Process .Args ), len (launchSpec .Cmd ))
162
166
}
163
167
164
- // TODO(b/212586174): Dial with secure credentials.
165
- opt := grpc .WithTransportCredentials (insecure .NewCredentials ())
166
- conn , err := grpc .Dial (launchSpec .AttestationServiceAddr , opt )
167
- if err != nil {
168
- return nil , fmt .Errorf ("failed to open connection to attestation service: %v" , err )
169
- }
170
- verifierClient := grpcclient .NewClient (conn , logger )
171
-
172
168
// Fetch ID token with specific audience.
173
169
// See https://cloud.google.com/functions/docs/securing/authenticating#functions-bearer-token-example-go.
174
170
principalFetcher := func (audience string ) ([][]byte , error ) {
@@ -198,6 +194,21 @@ func NewRunner(ctx context.Context, cdClient *containerd.Client, token oauth2.To
198
194
return tokens , nil
199
195
}
200
196
197
+ asAddr := launchSpec .AttestationServiceAddr
198
+ var verifierClient verifier.Client
199
+ var conn * grpc.ClientConn
200
+ // Temporary support for both gRPC and REST-based attestation verifier.
201
+ // Use REST when empty flag or the presence of http in the addr, else gRPC.
202
+ // TODO: remove once fully migrated to the REST-based verifier.
203
+ if asAddr == "" || strings .Contains (asAddr , "http" ) {
204
+ verifierClient , err = getRESTClient (ctx , asAddr , launchSpec )
205
+ } else {
206
+ verifierClient , conn , err = getGRPCClient (asAddr , logger )
207
+ }
208
+ if err != nil {
209
+ return nil , fmt .Errorf ("failed to create verifier client: %v" , err )
210
+ }
211
+
201
212
return & ContainerRunner {
202
213
container ,
203
214
launchSpec ,
@@ -207,6 +218,39 @@ func NewRunner(ctx context.Context, cdClient *containerd.Client, token oauth2.To
207
218
}, nil
208
219
}
209
220
221
+ // getGRPCClient returns a gRPC verifier.Client pointing to the given address.
222
+ // It also returns a grpc.ClientConn for closing out the connection.
223
+ func getGRPCClient (asAddr string , logger * log.Logger ) (verifier.Client , * grpc.ClientConn , error ) {
224
+ opt := grpc .WithTransportCredentials (insecure .NewCredentials ())
225
+ conn , err := grpc .Dial (asAddr , opt )
226
+ if err != nil {
227
+ return nil , nil , fmt .Errorf ("failed to open connection to gRPC attestation service: %v" , err )
228
+ }
229
+ return grpcclient .NewClient (conn , logger ), conn , nil
230
+ }
231
+
232
+ // getRESTClient returns a REST verifier.Client that points to the given address.
233
+ // It defaults to the Attestation Verifier instance at
234
+ // https://confidentialcomputing.googleapis.com.
235
+ func getRESTClient (ctx context.Context , asAddr string , spec spec.LauncherSpec ) (verifier.Client , error ) {
236
+ httpClient , err := google .DefaultClient (ctx )
237
+ if err != nil {
238
+ return nil , fmt .Errorf ("failed to create HTTP client: %v" , err )
239
+ }
240
+
241
+ opts := []option.ClientOption {option .WithHTTPClient (httpClient )}
242
+ if asAddr != "" {
243
+ opts = append (opts , option .WithEndpoint (asAddr ))
244
+ }
245
+
246
+ const defaultRegion = "us-central1"
247
+ restClient , err := rest .NewClient (ctx , spec .ProjectID , defaultRegion , opts ... )
248
+ if err != nil {
249
+ return nil , err
250
+ }
251
+ return restClient , nil
252
+ }
253
+
210
254
// parseEnvVars parses the environment variables to the oci format
211
255
func parseEnvVars (envVars []spec.EnvVar ) []string {
212
256
var result []string
@@ -433,5 +477,7 @@ func (r *ContainerRunner) Close(ctx context.Context) {
433
477
// Exit gracefully:
434
478
// Delete container and close connection to attestation service.
435
479
r .container .Delete (ctx , containerd .WithSnapshotCleanup )
436
- r .attestConn .Close ()
480
+ if r .attestConn != nil {
481
+ r .attestConn .Close ()
482
+ }
437
483
}
0 commit comments