Skip to content

Commit

Permalink
Support non-Sigstore TSA requests (#2708)
Browse files Browse the repository at this point in the history
* Support non-Sigstore TSA requests

This changes the client to instead simply exchange a TSQ for a TSR given
a URL to the API. This will mean that for clients using timestamping
currently, they will need to update their Cosign calls to use the full
path (e.g. tsa.sigstore/api/v1/timestamp)

Fixes #2704

Signed-off-by: Hayden Blauzvern <[email protected]>

* Address comments

Signed-off-by: Hayden Blauzvern <[email protected]>

---------

Signed-off-by: Hayden Blauzvern <[email protected]>
  • Loading branch information
haydentherapper authored Feb 16, 2023
1 parent c7afc3b commit d15ed74
Show file tree
Hide file tree
Showing 21 changed files with 162 additions and 159 deletions.
9 changes: 2 additions & 7 deletions cmd/cosign/cli/attest/attest.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ import (
"github.com/sigstore/cosign/v2/cmd/cosign/cli/rekor"
"github.com/sigstore/cosign/v2/cmd/cosign/cli/sign"
"github.com/sigstore/cosign/v2/internal/pkg/cosign/tsa"
tsaclient "github.com/sigstore/cosign/v2/internal/pkg/cosign/tsa/client"
"github.com/sigstore/cosign/v2/internal/ui"
"github.com/sigstore/cosign/v2/pkg/cosign"
"github.com/sigstore/cosign/v2/pkg/cosign/attestation"
Expand All @@ -45,7 +46,6 @@ import (
"github.com/sigstore/rekor/pkg/generated/models"
"github.com/sigstore/sigstore/pkg/signature/dsse"
signatureoptions "github.com/sigstore/sigstore/pkg/signature/options"
tsaclient "github.com/sigstore/timestamp-authority/pkg/client"
)

type tlogUploadFn func(*client.Rekor, []byte) (*models.LogEntryAnon, error)
Expand Down Expand Up @@ -173,13 +173,8 @@ func (c *AttestCommand) Exec(ctx context.Context, imageRef string) error {
opts = append(opts, static.WithCertChain(sv.Cert, sv.Chain))
}
if c.KeyOpts.TSAServerURL != "" {
clientTSA, err := tsaclient.GetTimestampClient(c.KeyOpts.TSAServerURL)
if err != nil {
return fmt.Errorf("failed to create TSA client: %w", err)
}

// Here we get the response from the timestamped authority server
responseBytes, err := tsa.GetTimestampedSignature(signedPayload, clientTSA)
responseBytes, err := tsa.GetTimestampedSignature(signedPayload, tsaclient.NewTSAClient(c.KeyOpts.TSAServerURL))
if err != nil {
return err
}
Expand Down
8 changes: 2 additions & 6 deletions cmd/cosign/cli/attest/attest_blob.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ import (
"github.com/sigstore/cosign/v2/cmd/cosign/cli/rekor"
"github.com/sigstore/cosign/v2/cmd/cosign/cli/sign"
"github.com/sigstore/cosign/v2/internal/pkg/cosign/tsa"
"github.com/sigstore/cosign/v2/internal/pkg/cosign/tsa/client"
"github.com/sigstore/cosign/v2/pkg/cosign"
"github.com/sigstore/cosign/v2/pkg/cosign/attestation"
cbundle "github.com/sigstore/cosign/v2/pkg/cosign/bundle"
Expand All @@ -42,7 +43,6 @@ import (
"github.com/sigstore/sigstore/pkg/signature"
"github.com/sigstore/sigstore/pkg/signature/dsse"
signatureoptions "github.com/sigstore/sigstore/pkg/signature/options"
tsaclient "github.com/sigstore/timestamp-authority/pkg/client"
)

// nolint
Expand Down Expand Up @@ -145,11 +145,7 @@ func (c *AttestBlobCommand) Exec(ctx context.Context, artifactPath string) error

var rfc3161Timestamp *cbundle.RFC3161Timestamp
if c.TSAServerURL != "" {
clientTSA, err := tsaclient.GetTimestampClient(c.TSAServerURL)
if err != nil {
return fmt.Errorf("failed to create TSA client: %w", err)
}
respBytes, err := tsa.GetTimestampedSignature(sig, clientTSA)
respBytes, err := tsa.GetTimestampedSignature(sig, client.NewTSAClient(c.TSAServerURL))
if err != nil {
return err
}
Expand Down
2 changes: 1 addition & 1 deletion cmd/cosign/cli/options/attest.go
Original file line number Diff line number Diff line change
Expand Up @@ -81,5 +81,5 @@ func (o *AttestOptions) AddFlags(cmd *cobra.Command) {
"whether or not to upload to the tlog")

cmd.Flags().StringVar(&o.TSAServerURL, "timestamp-server-url", "",
"url to the Timestamp RFC3161 server, default none")
"url to the Timestamp RFC3161 server, default none. Must be the path to the API to request timestamp responses, e.g. https://freetsa.org/tsr")
}
2 changes: 1 addition & 1 deletion cmd/cosign/cli/options/attest_blob.go
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,7 @@ func (o *AttestBlobOptions) AddFlags(cmd *cobra.Command) {
"whether or not to upload to the tlog")

cmd.Flags().StringVar(&o.TSAServerURL, "timestamp-server-url", "",
"url to the Timestamp RFC3161 server, default none")
"url to the Timestamp RFC3161 server, default none. Must be the path to the API to request timestamp responses, e.g. https://freetsa.org/tsr")

cmd.Flags().StringVar(&o.RFC3161TimestampPath, "rfc3161-timestamp-bundle", "",
"path to an RFC 3161 timestamp bundle FILE")
Expand Down
2 changes: 1 addition & 1 deletion cmd/cosign/cli/options/policy.go
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ func (o *PolicySignOptions) AddFlags(cmd *cobra.Command) {
"whether or not to upload to the tlog")

cmd.Flags().StringVar(&o.TSAServerURL, "timestamp-server-url", "",
"url to the Timestamp RFC3161 server, default none")
"url to the Timestamp RFC3161 server, default none. Must be the path to the API to request timestamp responses, e.g. https://freetsa.org/tsr")

o.Registry.AddFlags(cmd)
o.Fulcio.AddFlags(cmd)
Expand Down
2 changes: 1 addition & 1 deletion cmd/cosign/cli/options/sign.go
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,7 @@ func (o *SignOptions) AddFlags(cmd *cobra.Command) {
"whether or not to upload to the tlog")

cmd.Flags().StringVar(&o.TSAServerURL, "timestamp-server-url", "",
"url to the Timestamp RFC3161 server, default none")
"url to the Timestamp RFC3161 server, default none. Must be the path to the API to request timestamp responses, e.g. https://freetsa.org/tsr")

cmd.Flags().BoolVar(&o.IssueCertificate, "issue-certificate", false,
"issue a code signing certificate from Fulcio, even if a key is provided")
Expand Down
2 changes: 1 addition & 1 deletion cmd/cosign/cli/options/signblob.go
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ func (o *SignBlobOptions) AddFlags(cmd *cobra.Command) {
"whether or not to upload to the tlog")

cmd.Flags().StringVar(&o.TSAServerURL, "timestamp-server-url", "",
"url to the Timestamp RFC3161 server, default none")
"url to the Timestamp RFC3161 server, default none. Must be the path to the API to request timestamp responses, e.g. https://freetsa.org/tsr")

cmd.Flags().StringVar(&o.RFC3161TimestampPath, "rfc3161-timestamp", "",
"write the RFC3161 timestamp to a file")
Expand Down
8 changes: 2 additions & 6 deletions cmd/cosign/cli/policy_init.go
Original file line number Diff line number Diff line change
Expand Up @@ -38,8 +38,8 @@ import (
"github.com/sigstore/cosign/v2/cmd/cosign/cli/sign"
"github.com/sigstore/cosign/v2/cmd/cosign/cli/upload"
"github.com/sigstore/cosign/v2/internal/pkg/cosign/tsa"
"github.com/sigstore/cosign/v2/internal/pkg/cosign/tsa/client"
"github.com/sigstore/sigstore/pkg/cryptoutils"
tsaclient "github.com/sigstore/timestamp-authority/pkg/client"

"github.com/sigstore/cosign/v2/pkg/cosign"
cremote "github.com/sigstore/cosign/v2/pkg/cosign/remote"
Expand Down Expand Up @@ -268,12 +268,8 @@ func signPolicy() *cobra.Command {
}

if o.TSAServerURL != "" {
clientTSA, err := tsaclient.GetTimestampClient(o.TSAServerURL)
if err != nil {
return fmt.Errorf("failed to create TSA client: %w", err)
}
// Here we get the response from the timestamped authority server
if _, err := tsa.GetTimestampedSignature(signed.Signed, clientTSA); err != nil {
if _, err := tsa.GetTimestampedSignature(signed.Signed, client.NewTSAClient(o.TSAServerURL)); err != nil {
return err
}
}
Expand Down
9 changes: 2 additions & 7 deletions cmd/cosign/cli/sign/sign.go
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ import (
ipayload "github.com/sigstore/cosign/v2/internal/pkg/cosign/payload"
irekor "github.com/sigstore/cosign/v2/internal/pkg/cosign/rekor"
"github.com/sigstore/cosign/v2/internal/pkg/cosign/tsa"
"github.com/sigstore/cosign/v2/internal/pkg/cosign/tsa/client"
"github.com/sigstore/cosign/v2/internal/ui"
"github.com/sigstore/cosign/v2/pkg/cosign"
"github.com/sigstore/cosign/v2/pkg/cosign/pivkey"
Expand All @@ -55,7 +56,6 @@ import (
"github.com/sigstore/sigstore/pkg/signature"
signatureoptions "github.com/sigstore/sigstore/pkg/signature/options"
sigPayload "github.com/sigstore/sigstore/pkg/signature/payload"
tsaclient "github.com/sigstore/timestamp-authority/pkg/client"

// Loads OIDC providers
_ "github.com/sigstore/cosign/v2/pkg/providers/all"
Expand Down Expand Up @@ -237,12 +237,7 @@ func signDigest(ctx context.Context, digest name.Digest, payload []byte, ko opti
}

if ko.TSAServerURL != "" {
clientTSA, err := tsaclient.GetTimestampClient(ko.TSAServerURL)
if err != nil {
return fmt.Errorf("failed to create TSA client: %w", err)
}

s = tsa.NewSigner(s, clientTSA)
s = tsa.NewSigner(s, client.NewTSAClient(ko.TSAServerURL))
}
shouldUpload, err := ShouldUploadToTlog(ctx, ko, digest, tlogUpload)
if err != nil {
Expand Down
9 changes: 2 additions & 7 deletions cmd/cosign/cli/sign/sign_blob.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,8 @@ import (
"path/filepath"

"github.com/sigstore/cosign/v2/internal/pkg/cosign/tsa"
"github.com/sigstore/cosign/v2/internal/pkg/cosign/tsa/client"
cbundle "github.com/sigstore/cosign/v2/pkg/cosign/bundle"
tsaclient "github.com/sigstore/timestamp-authority/pkg/client"

"github.com/sigstore/cosign/v2/cmd/cosign/cli/options"
"github.com/sigstore/cosign/v2/cmd/cosign/cli/rekor"
Expand Down Expand Up @@ -77,12 +77,7 @@ func SignBlobCmd(ro *options.RootOptions, ko options.KeyOpts, payloadPath string
return nil, fmt.Errorf("timestamp output path must be set")
}

clientTSA, err := tsaclient.GetTimestampClient(ko.TSAServerURL)
if err != nil {
return nil, fmt.Errorf("failed to create TSA client: %w", err)
}

respBytes, err := tsa.GetTimestampedSignature(sig, clientTSA)
respBytes, err := tsa.GetTimestampedSignature(sig, client.NewTSAClient(ko.TSAServerURL))
if err != nil {
return nil, err
}
Expand Down
34 changes: 15 additions & 19 deletions cmd/cosign/cli/verify/verify_blob_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,6 @@ import (
"github.com/sigstore/sigstore/pkg/signature"
"github.com/sigstore/sigstore/pkg/signature/dsse"
signatureoptions "github.com/sigstore/sigstore/pkg/signature/options"
"github.com/sigstore/timestamp-authority/pkg/generated/client/timestamp"
)

func TestSignaturesRef(t *testing.T) {
Expand Down Expand Up @@ -195,38 +194,36 @@ func TestVerifyBlob(t *testing.T) {
if err != nil {
t.Fatal(err)
}
tsChain, err := tsaClient.Timestamp.GetTimestampCertChain(nil)
certChainPEM, err := cryptoutils.MarshalCertificatesToPEM(tsaClient.CertChain)
if err != nil {
t.Fatalf("unexpected error getting timestamp chain: %v", err)
t.Fatalf("unexpected error marshalling cert chain: %v", err)
}
expiredTSACertChainPath := filepath.Join(td, "exptsacertchain.pem")
if err := os.WriteFile(expiredTSACertChainPath, []byte(tsChain.Payload), 0644); err != nil {
if err := os.WriteFile(expiredTSACertChainPath, certChainPEM, 0644); err != nil {
t.Fatal(err)
}
var tsRespBytes bytes.Buffer
_, err = tsaClient.Timestamp.GetTimestampResponse(&timestamp.GetTimestampResponseParams{}, &tsRespBytes)
tsr, err := tsaClient.GetTimestampResponse(nil)
if err != nil {
t.Fatalf("unable to generate a timestamp response: %v", err)
}
rfc3161Timestamp := &bundle.RFC3161Timestamp{SignedRFC3161Timestamp: tsRespBytes.Bytes()}
rfc3161Timestamp := &bundle.RFC3161Timestamp{SignedRFC3161Timestamp: tsr}
expiredTSPath := writeTimestampFile(t, td, rfc3161Timestamp, "expiredrfc3161TS.json")
tsaClient, err = mock.NewTSAClient(unexpiredTSAOpts)
if err != nil {
t.Fatal(err)
}
tsRespBytes.Reset()
_, err = tsaClient.Timestamp.GetTimestampResponse(&timestamp.GetTimestampResponseParams{}, &tsRespBytes)
tsr, err = tsaClient.GetTimestampResponse(nil)
if err != nil {
t.Fatalf("unable to generate a timestamp response: %v", err)
}
rfc3161Timestamp = &bundle.RFC3161Timestamp{SignedRFC3161Timestamp: tsRespBytes.Bytes()}
rfc3161Timestamp = &bundle.RFC3161Timestamp{SignedRFC3161Timestamp: tsr}
unexpiredTSPath := writeTimestampFile(t, td, rfc3161Timestamp, "unexpiredrfc3161TS.json")
tsChain, err = tsaClient.Timestamp.GetTimestampCertChain(nil)
certChainPEM, err = cryptoutils.MarshalCertificatesToPEM(tsaClient.CertChain)
if err != nil {
t.Fatalf("unexpected error getting timestamp chain: %v", err)
t.Fatalf("unexpected error marshalling cert chain: %v", err)
}
unexpiredTSACertChainPath := filepath.Join(td, "unexptsacertchain.pem")
if err := os.WriteFile(unexpiredTSACertChainPath, []byte(tsChain.Payload), 0644); err != nil {
if err := os.WriteFile(unexpiredTSACertChainPath, certChainPEM, 0644); err != nil {
t.Fatal(err)
}

Expand Down Expand Up @@ -1073,20 +1070,19 @@ func TestVerifyBlobCmdWithBundle(t *testing.T) {
if err != nil {
t.Fatal(err)
}
tsChain, err := tsaClient.Timestamp.GetTimestampCertChain(nil)
certChainPEM, err := cryptoutils.MarshalCertificatesToPEM(tsaClient.CertChain)
if err != nil {
t.Fatalf("unexpected error getting timestamp chain: %v", err)
t.Fatalf("unexpected error marshalling cert chain: %v", err)
}
tsaCertChainPath := filepath.Join(keyless.td, "tsacertchain.pem")
if err := os.WriteFile(tsaCertChainPath, []byte(tsChain.Payload), 0644); err != nil {
if err := os.WriteFile(tsaCertChainPath, certChainPEM, 0644); err != nil {
t.Fatal(err)
}
var tsRespBytes bytes.Buffer
_, err = tsaClient.Timestamp.GetTimestampResponse(&timestamp.GetTimestampResponseParams{}, &tsRespBytes)
tsr, err := tsaClient.GetTimestampResponse(nil)
if err != nil {
t.Fatalf("unable to generate a timestamp response: %v", err)
}
rfc3161Timestamp := &bundle.RFC3161Timestamp{SignedRFC3161Timestamp: tsRespBytes.Bytes()}
rfc3161Timestamp := &bundle.RFC3161Timestamp{SignedRFC3161Timestamp: tsr}
tsPath := writeTimestampFile(t, keyless.td, rfc3161Timestamp, "rfc3161TS.json")

entry := genRekorEntry(t, hashedrekord.KIND, hashedrekord.New().DefaultVersion(), []byte(blob), leafPemCert, sig)
Expand Down
2 changes: 1 addition & 1 deletion doc/cosign_attest-blob.md

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion doc/cosign_attest.md

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion doc/cosign_policy_sign.md

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion doc/cosign_sign-blob.md

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion doc/cosign_sign.md

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading

0 comments on commit d15ed74

Please sign in to comment.