diff --git a/internal/commands/root/sign.go b/internal/commands/root/sign.go index d1ff55a4..1e9f3ec6 100644 --- a/internal/commands/root/sign.go +++ b/internal/commands/root/sign.go @@ -73,7 +73,7 @@ func commandSign(o *options, s *gsio.Streams, args ...string) error { return fmt.Errorf("failed to read message from stdin: %w", err) } - rekor, err := rekor.NewClient(o.Config.Rekor) + rekor, err := rekor.NewClientContext(ctx, o.Config.Rekor) if err != nil { return fmt.Errorf("failed to create rekor client: %w", err) } diff --git a/internal/gitsign/gitsign.go b/internal/gitsign/gitsign.go index fbf7b6f2..b881bf04 100644 --- a/internal/gitsign/gitsign.go +++ b/internal/gitsign/gitsign.go @@ -74,7 +74,7 @@ func NewVerifierWithCosignOpts(ctx context.Context, cfg *config.Config, opts *co return nil, fmt.Errorf("error creating Git verifier: %w", err) } - rekor, err := rekorinternal.NewClient(cfg.Rekor) + rekor, err := rekorinternal.NewClientContext(ctx, cfg.Rekor) if err != nil { return nil, fmt.Errorf("failed to create rekor client: %w", err) } diff --git a/internal/rekor/client.go b/internal/rekor/client.go index 604ddc7c..3d52fc28 100644 --- a/internal/rekor/client.go +++ b/internal/rekor/client.go @@ -15,11 +15,19 @@ package rekor import ( + "context" + gitrekor "github.com/sigstore/gitsign/pkg/rekor" rekor "github.com/sigstore/rekor/pkg/client" ) // NewClient returns a new Rekor client with common client options set. +// Deprecated: Use NewClientContext instead. func NewClient(url string) (*gitrekor.Client, error) { - return gitrekor.New(url, rekor.WithUserAgent("gitsign")) + return NewClientContext(context.TODO(), url) +} + +// NewClientContext returns a new Rekor client with common client options set. +func NewClientContext(ctx context.Context, url string) (*gitrekor.Client, error) { + return gitrekor.NewWithOptions(ctx, url, gitrekor.WithClientOption(rekor.WithUserAgent("gitsign"))) } diff --git a/pkg/rekor/option.go b/pkg/rekor/option.go new file mode 100644 index 00000000..36d3b12d --- /dev/null +++ b/pkg/rekor/option.go @@ -0,0 +1,45 @@ +// +// Copyright 2023 The Sigstore Authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package rekor + +import ( + "context" + + "github.com/sigstore/cosign/v2/pkg/cosign" + "github.com/sigstore/rekor/pkg/client" +) + +type Option func(*options) + +type options struct { + rekorPublicKeys CosignRekorKeyProvider + clientOpts []client.Option +} + +// CosignRekorKeyProvider is a function that returns the Rekor public keys in cosign's specialized format. +type CosignRekorKeyProvider func(ctx context.Context) (*cosign.TrustedTransparencyLogPubKeys, error) + +func WithCosignRekorKeyProvider(f CosignRekorKeyProvider) Option { + return func(o *options) { + o.rekorPublicKeys = f + } +} + +func WithClientOption(opts ...client.Option) Option { + return func(o *options) { + o.clientOpts = opts + } +} diff --git a/pkg/rekor/rekor.go b/pkg/rekor/rekor.go index 6d5a39e4..d6bcdaa3 100644 --- a/pkg/rekor/rekor.go +++ b/pkg/rekor/rekor.go @@ -43,7 +43,6 @@ import ( hashedrekord_v001 "github.com/sigstore/rekor/pkg/types/hashedrekord/v0.0.1" rekord_v001 "github.com/sigstore/rekor/pkg/types/rekord/v0.0.1" "github.com/sigstore/sigstore/pkg/cryptoutils" - "github.com/sigstore/sigstore/pkg/tuf" ) // Verifier represents a mechanism to get and verify Rekor entries for the given Git data. @@ -64,12 +63,26 @@ type Client struct { publicKeys *cosign.TrustedTransparencyLogPubKeys } +// Deprecated: Use NewWithOptions instead. func New(url string, opts ...rekor.Option) (*Client, error) { - c, err := rekor.GetRekorClient(url, opts...) + return NewWithOptions(context.TODO(), url, WithClientOption(opts...)) +} + +func NewWithOptions(ctx context.Context, url string, opts ...Option) (*Client, error) { + // Defaults + o := &options{ + rekorPublicKeys: cosign.GetRekorPubs, + } + for _, f := range opts { + f(o) + } + + c, err := rekor.GetRekorClient(url, o.clientOpts...) if err != nil { return nil, err } - pubs, err := rekorPubsFromClient(c) + + pubs, err := o.rekorPublicKeys(ctx) if err != nil { return nil, err } @@ -158,21 +171,6 @@ func (c *Client) findTLogEntriesByPayloadAndPK(ctx context.Context, payload, pub return searchIndex.GetPayload(), nil } -// rekorPubsFromClient returns a RekorPubKey keyed by the log ID from the Rekor client. -// NOTE: This **must not** be used in the verification path, but may be used in the -// sign path to validate return responses are consistent from Rekor. -func rekorPubsFromClient(rekorClient *client.Rekor) (*cosign.TrustedTransparencyLogPubKeys, error) { - publicKeys := cosign.NewTrustedTransparencyLogPubKeys() - pubOK, err := rekorClient.Pubkey.GetPublicKey(nil) - if err != nil { - return nil, fmt.Errorf("unable to fetch rekor public key from rekor: %w", err) - } - if err := publicKeys.AddTransparencyLogPubKey([]byte(pubOK.Payload), tuf.Active); err != nil { - return nil, fmt.Errorf("constructRekorPubKey: %w", err) - } - return &publicKeys, nil -} - // Verify verifies a commit using online verification. // // This is done by: