Skip to content

Commit

Permalink
plumb context through to tlog requests (#1103)
Browse files Browse the repository at this point in the history
Signed-off-by: Jake Sanders <jsand@google.com>
  • Loading branch information
Jake Sanders committed Nov 24, 2021
1 parent fcc8256 commit 6fc942b
Show file tree
Hide file tree
Showing 7 changed files with 69 additions and 52 deletions.
8 changes: 7 additions & 1 deletion cmd/cosign/cli/attest/attest.go
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,12 @@ func AttestCmd(ctx context.Context, ko sign.KeyOpts, regOpts options.RegistryOpt
return errors.Wrap(err, "parsing reference")
}

if timeout != 0 {
var cancelFn context.CancelFunc
ctx, cancelFn = context.WithTimeout(ctx, timeout)
defer cancelFn()
}

ociremoteOpts, err := regOpts.ClientOpts(ctx)
if err != nil {
return err
Expand Down Expand Up @@ -128,7 +134,7 @@ func AttestCmd(ctx context.Context, ko sign.KeyOpts, regOpts options.RegistryOpt
// Check whether we should be uploading to the transparency log
if sign.ShouldUploadToTlog(ctx, digest, force, ko.RekorURL) {
bundle, err := sign.UploadToTlog(ctx, sv, ko.RekorURL, func(r *client.Rekor, b []byte) (*models.LogEntryAnon, error) {
return cosign.TLogUploadInTotoAttestation(r, signedPayload, b, timeout)
return cosign.TLogUploadInTotoAttestation(ctx, r, signedPayload, b)
})
if err != nil {
return err
Expand Down
20 changes: 14 additions & 6 deletions cmd/cosign/cli/policy_init.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ package cli

import (
"bytes"
"context"
"encoding/base64"
"encoding/json"
"fmt"
Expand Down Expand Up @@ -166,8 +167,15 @@ func signPolicy() *cobra.Command {
Short: "sign a keyless policy.",
Long: "policy is used to manage a root.json policy\nfor keyless signing delegation. This is used to establish a policy for a registry namespace,\na signing threshold and a list of maintainers who can sign over the body section.",
RunE: func(cmd *cobra.Command, args []string) error {
ctx := cmd.Context()
if o.Timeout != 0 {
var cancelFn context.CancelFunc
ctx, cancelFn = context.WithTimeout(ctx, o.Timeout)
defer cancelFn()
}

// Get Fulcio signer
sv, err := sign.SignerFromKeyOpts(cmd.Context(), "", sign.KeyOpts{
sv, err := sign.SignerFromKeyOpts(ctx, "", sign.KeyOpts{
FulcioURL: o.Fulcio.URL,
IDToken: o.Fulcio.IdentityToken,
InsecureSkipFulcioVerify: o.Fulcio.InsecureSkipFulcioVerify,
Expand Down Expand Up @@ -199,7 +207,7 @@ func signPolicy() *cobra.Command {
}
opts := []remote.Option{
remote.WithAuthFromKeychain(authn.DefaultKeychain),
remote.WithContext(cmd.Context()),
remote.WithContext(ctx),
}

img, err := remote.Image(ref, opts...)
Expand All @@ -212,7 +220,7 @@ func signPolicy() *cobra.Command {
}

result := &bytes.Buffer{}
if err := sget.New(imgName+"@"+dgst.String(), "", result).Do(cmd.Context()); err != nil {
if err := sget.New(imgName+"@"+dgst.String(), "", result).Do(ctx); err != nil {
return errors.Wrap(err, "error getting result")
}
b, err := io.ReadAll(result)
Expand All @@ -228,7 +236,7 @@ func signPolicy() *cobra.Command {

// Create and add signature
key := tuf.FulcioVerificationKey(signerEmail, signerIssuer)
sig, err := sv.SignMessage(bytes.NewReader(signed.Signed), signatureoptions.WithContext(cmd.Context()))
sig, err := sv.SignMessage(bytes.NewReader(signed.Signed), signatureoptions.WithContext(ctx))
if err != nil {
return errors.Wrap(err, "error occurred while during artifact signing")
}
Expand All @@ -248,7 +256,7 @@ func signPolicy() *cobra.Command {
if err != nil {
return err
}
entry, err := cosign.TLogUpload(rekorClient, sig, signed.Signed, rekorBytes, o.Timeout)
entry, err := cosign.TLogUpload(ctx, rekorClient, sig, signed.Signed, rekorBytes)
if err != nil {
return err
}
Expand Down Expand Up @@ -281,7 +289,7 @@ func signPolicy() *cobra.Command {
cremote.FileFromFlag(outfile),
}

return upload.BlobCmd(cmd.Context(), o.Registry, files, "", rootPath(o.ImageRef))
return upload.BlobCmd(ctx, o.Registry, files, "", rootPath(o.ImageRef))
},
}

Expand Down
11 changes: 8 additions & 3 deletions cmd/cosign/cli/sign/sign.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,6 @@ import (
"os"
"path/filepath"
"strings"
"time"

"github.com/google/go-containerregistry/pkg/name"
v1 "github.com/google/go-containerregistry/pkg/v1"
Expand Down Expand Up @@ -135,6 +134,13 @@ func SignCmd(ctx context.Context, ko KeyOpts, regOpts options.RegistryOptions, a
}
}

// TODO: accept a timeout argument and uncomment the block below
// if timeout != 0 {
// var cancelFn context.CancelFunc
// ctx, cancelFn = context.WithTimeout(ctx, timeout)
// defer cancelFn()
// }

sv, err := SignerFromKeyOpts(ctx, certPath, ko)
if err != nil {
return errors.Wrap(err, "getting signer")
Expand Down Expand Up @@ -252,8 +258,7 @@ func signDigest(ctx context.Context, digest name.Digest, payload []byte, ko KeyO
}
if ShouldUploadToTlog(ctx, digest, force, ko.RekorURL) {
bundle, err := UploadToTlog(ctx, sv, ko.RekorURL, func(r *rekGenClient.Rekor, b []byte) (*models.LogEntryAnon, error) {
// TODO - Defaulting the timeout to zero as the CLI doesn't accept timeout.
return cosign.TLogUpload(r, signature, payload, b, time.Duration(0))
return cosign.TLogUpload(ctx, r, signature, payload, b)
})
if err != nil {
return err
Expand Down
7 changes: 6 additions & 1 deletion cmd/cosign/cli/sign/sign_blob.go
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,11 @@ func SignBlobCmd(ctx context.Context, ko KeyOpts, regOpts options.RegistryOption
if err != nil {
return nil, err
}
if timeout != 0 {
var cancelFn context.CancelFunc
ctx, cancelFn = context.WithTimeout(ctx, timeout)
defer cancelFn()
}

sv, err := SignerFromKeyOpts(ctx, "", ko)
if err != nil {
Expand Down Expand Up @@ -94,7 +99,7 @@ func SignBlobCmd(ctx context.Context, ko KeyOpts, regOpts options.RegistryOption
if err != nil {
return nil, err
}
entry, err := cosign.TLogUpload(rekorClient, sig, payload, rekorBytes, timeout)
entry, err := cosign.TLogUpload(ctx, rekorClient, sig, payload, rekorBytes)
if err != nil {
return nil, err
}
Expand Down
6 changes: 3 additions & 3 deletions cmd/cosign/cli/verify/verify_blob.go
Original file line number Diff line number Diff line change
Expand Up @@ -142,7 +142,7 @@ func VerifyBlobCmd(ctx context.Context, ko sign.KeyOpts, certRef, sigRef, blobRe
return err
}

uuids, err := cosign.FindTLogEntriesByPayload(rClient, blobBytes)
uuids, err := cosign.FindTLogEntriesByPayload(ctx, rClient, blobBytes)
if err != nil {
return err
}
Expand All @@ -151,7 +151,7 @@ func VerifyBlobCmd(ctx context.Context, ko sign.KeyOpts, certRef, sigRef, blobRe
return errors.New("could not find a tlog entry for provided blob")
}

tlogEntry, err := cosign.GetTlogEntry(rClient, uuids[0])
tlogEntry, err := cosign.GetTlogEntry(ctx, rClient, uuids[0])
if err != nil {
return err
}
Expand Down Expand Up @@ -206,7 +206,7 @@ func VerifyBlobCmd(ctx context.Context, ko sign.KeyOpts, certRef, sigRef, blobRe
return err
}
}
uuid, index, err := cosign.FindTlogEntry(rekorClient, b64sig, blobBytes, pubBytes)
uuid, index, err := cosign.FindTlogEntry(ctx, rekorClient, b64sig, blobBytes, pubBytes)
if err != nil {
return err
}
Expand Down
43 changes: 18 additions & 25 deletions pkg/cosign/tlog.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,6 @@ import (
"encoding/hex"
"fmt"
"strings"
"time"

"github.com/go-openapi/strfmt"
"github.com/go-openapi/swag"
Expand All @@ -44,8 +43,7 @@ import (
// This is the rekor public key target name
var rekorTargetStr = `rekor.pub`

func GetRekorPub() string {
ctx := context.Background() // TODO: pass in context?
func GetRekorPub(ctx context.Context) string {
buf := tuf.ByteDestination{Buffer: &bytes.Buffer{}}
// Retrieves the rekor public key from the embedded or cached TUF root. If expired, makes a
// network call to retrieve the updated target.
Expand All @@ -56,32 +54,27 @@ func GetRekorPub() string {
}

// TLogUpload will upload the signature, public key and payload to the transparency log.
func TLogUpload(rekorClient *client.Rekor, signature, payload []byte, pemBytes []byte, timeout time.Duration) (*models.LogEntryAnon, error) {
func TLogUpload(ctx context.Context, rekorClient *client.Rekor, signature, payload []byte, pemBytes []byte) (*models.LogEntryAnon, error) {
re := rekorEntry(payload, signature, pemBytes)
returnVal := models.Rekord{
APIVersion: swag.String(re.APIVersion()),
Spec: re.RekordObj,
}
return doUpload(rekorClient, &returnVal, timeout)
return doUpload(ctx, rekorClient, &returnVal)
}

// TLogUploadInTotoAttestation will upload and in-toto entry for the signature and public key to the transparency log.
func TLogUploadInTotoAttestation(rekorClient *client.Rekor, signature, pemBytes []byte, timeout time.Duration) (*models.LogEntryAnon, error) {
func TLogUploadInTotoAttestation(ctx context.Context, rekorClient *client.Rekor, signature, pemBytes []byte) (*models.LogEntryAnon, error) {
e := intotoEntry(signature, pemBytes)
returnVal := models.Intoto{
APIVersion: swag.String(e.APIVersion()),
Spec: e.IntotoObj,
}
return doUpload(rekorClient, &returnVal, timeout)
return doUpload(ctx, rekorClient, &returnVal)
}

func doUpload(rekorClient *client.Rekor, pe models.ProposedEntry, timeout time.Duration) (*models.LogEntryAnon, error) {
var params *entries.CreateLogEntryParams
if timeout != time.Duration(0) {
params = entries.NewCreateLogEntryParamsWithTimeout(timeout)
} else {
params = entries.NewCreateLogEntryParams()
}
func doUpload(ctx context.Context, rekorClient *client.Rekor, pe models.ProposedEntry) (*models.LogEntryAnon, error) {
params := entries.NewCreateLogEntryParamsWithContext(ctx)
params.SetProposedEntry(pe)
resp, err := rekorClient.Entries.CreateLogEntry(params)
if err != nil {
Expand All @@ -92,7 +85,7 @@ func doUpload(rekorClient *client.Rekor, pe models.ProposedEntry, timeout time.D
fmt.Println("Signature already exists. Displaying proof")
uriSplit := strings.Split(existsErr.Location.String(), "/")
uuid := uriSplit[len(uriSplit)-1]
return verifyTLogEntry(rekorClient, uuid)
return verifyTLogEntry(ctx, rekorClient, uuid)
}
return nil, err
}
Expand Down Expand Up @@ -132,8 +125,8 @@ func rekorEntry(payload, signature, pubKey []byte) rekord_v001.V001Entry {
}
}

func GetTlogEntry(rekorClient *client.Rekor, uuid string) (*models.LogEntryAnon, error) {
params := entries.NewGetLogEntryByUUIDParams()
func GetTlogEntry(ctx context.Context, rekorClient *client.Rekor, uuid string) (*models.LogEntryAnon, error) {
params := entries.NewGetLogEntryByUUIDParamsWithContext(ctx)
params.SetEntryUUID(uuid)
resp, err := rekorClient.Entries.GetLogEntryByUUID(params)
if err != nil {
Expand Down Expand Up @@ -172,8 +165,8 @@ func proposedEntry(b64Sig string, payload, pubKey []byte) ([]models.ProposedEntr
return proposedEntry, nil
}

func FindTlogEntry(rekorClient *client.Rekor, b64Sig string, payload, pubKey []byte) (uuid string, index int64, err error) {
searchParams := entries.NewSearchLogQueryParams()
func FindTlogEntry(ctx context.Context, rekorClient *client.Rekor, b64Sig string, payload, pubKey []byte) (uuid string, index int64, err error) {
searchParams := entries.NewSearchLogQueryParamsWithContext(ctx)
searchLogQuery := models.SearchLogQuery{}
proposedEntry, err := proposedEntry(b64Sig, payload, pubKey)
if err != nil {
Expand All @@ -200,15 +193,15 @@ func FindTlogEntry(rekorClient *client.Rekor, b64Sig string, payload, pubKey []b
for k := range logEntry {
uuid = k
}
verifiedEntry, err := verifyTLogEntry(rekorClient, uuid)
verifiedEntry, err := verifyTLogEntry(ctx, rekorClient, uuid)
if err != nil {
return "", 0, err
}
return uuid, *verifiedEntry.Verification.InclusionProof.LogIndex, nil
}

func FindTLogEntriesByPayload(rekorClient *client.Rekor, payload []byte) (uuids []string, err error) {
params := index.NewSearchIndexParams()
func FindTLogEntriesByPayload(ctx context.Context, rekorClient *client.Rekor, payload []byte) (uuids []string, err error) {
params := index.NewSearchIndexParamsWithContext(ctx)
params.Query = &models.SearchIndex{}

h := sha256.New()
Expand All @@ -222,8 +215,8 @@ func FindTLogEntriesByPayload(rekorClient *client.Rekor, payload []byte) (uuids
return searchIndex.GetPayload(), nil
}

func verifyTLogEntry(rekorClient *client.Rekor, uuid string) (*models.LogEntryAnon, error) {
params := entries.NewGetLogEntryByUUIDParams()
func verifyTLogEntry(ctx context.Context, rekorClient *client.Rekor, uuid string) (*models.LogEntryAnon, error) {
params := entries.NewGetLogEntryByUUIDParamsWithContext(ctx)
params.EntryUUID = uuid

lep, err := rekorClient.Entries.GetLogEntryByUUID(params)
Expand Down Expand Up @@ -254,7 +247,7 @@ func verifyTLogEntry(rekorClient *client.Rekor, uuid string) (*models.LogEntryAn
}

// Verify rekor's signature over the SET.
resp, err := rekorClient.Pubkey.GetPublicKey(pubkey.NewGetPublicKeyParams())
resp, err := rekorClient.Pubkey.GetPublicKey(pubkey.NewGetPublicKeyParamsWithContext(ctx))
if err != nil {
return nil, errors.Wrap(err, "rekor public key")
}
Expand Down
26 changes: 13 additions & 13 deletions pkg/cosign/verify.go
Original file line number Diff line number Diff line change
Expand Up @@ -139,7 +139,7 @@ func validateAndUnpackCert(cert *x509.Certificate, co *CheckOpts) (signature.Ver
return verifier, nil
}

func tlogValidatePublicKey(rekorClient *client.Rekor, pub crypto.PublicKey, sig oci.Signature) error {
func tlogValidatePublicKey(ctx context.Context, rekorClient *client.Rekor, pub crypto.PublicKey, sig oci.Signature) error {
pemBytes, err := cryptoutils.MarshalPublicKeyToPEM(pub)
if err != nil {
return err
Expand All @@ -152,11 +152,11 @@ func tlogValidatePublicKey(rekorClient *client.Rekor, pub crypto.PublicKey, sig
if err != nil {
return err
}
_, _, err = FindTlogEntry(rekorClient, b64sig, payload, pemBytes)
_, _, err = FindTlogEntry(ctx, rekorClient, b64sig, payload, pemBytes)
return err
}

func tlogValidateCertificate(rekorClient *client.Rekor, sig oci.Signature) error {
func tlogValidateCertificate(ctx context.Context, rekorClient *client.Rekor, sig oci.Signature) error {
cert, err := sig.Cert()
if err != nil {
return err
Expand All @@ -173,13 +173,13 @@ func tlogValidateCertificate(rekorClient *client.Rekor, sig oci.Signature) error
if err != nil {
return err
}
uuid, _, err := FindTlogEntry(rekorClient, b64sig, payload, pemBytes)
uuid, _, err := FindTlogEntry(ctx, rekorClient, b64sig, payload, pemBytes)
if err != nil {
return err
}
// if we have a cert, we should check expiry
// The IntegratedTime verified in VerifyTlog
e, err := GetTlogEntry(rekorClient, uuid)
e, err := GetTlogEntry(ctx, rekorClient, uuid)
if err != nil {
return err
}
Expand Down Expand Up @@ -249,7 +249,7 @@ func VerifyImageSignatures(ctx context.Context, signedImgRef name.Reference, co
}
}

verified, err := VerifyBundle(sig)
verified, err := VerifyBundle(ctx, sig)
if err != nil && co.RekorURL == "" {
return errors.Wrap(err, "unable to verify bundle")
}
Expand All @@ -261,10 +261,10 @@ func VerifyImageSignatures(ctx context.Context, signedImgRef name.Reference, co
if err != nil {
return err
}
return tlogValidatePublicKey(rekorClient, pub, sig)
return tlogValidatePublicKey(ctx, rekorClient, pub, sig)
}

return tlogValidateCertificate(rekorClient, sig)
return tlogValidateCertificate(ctx, rekorClient, sig)
}
return nil
}(sig); err != nil {
Expand Down Expand Up @@ -343,7 +343,7 @@ func VerifyImageAttestations(ctx context.Context, signedImgRef name.Reference, c
}
}

verified, err := VerifyBundle(att)
verified, err := VerifyBundle(ctx, att)
if err != nil && co.RekorURL == "" {
return errors.Wrap(err, "unable to verify bundle")
}
Expand All @@ -355,10 +355,10 @@ func VerifyImageAttestations(ctx context.Context, signedImgRef name.Reference, c
if err != nil {
return err
}
return tlogValidatePublicKey(rekorClient, pub, att)
return tlogValidatePublicKey(ctx, rekorClient, pub, att)
}

return tlogValidateCertificate(rekorClient, att)
return tlogValidateCertificate(ctx, rekorClient, att)
}
return nil
}(att); err != nil {
Expand Down Expand Up @@ -390,15 +390,15 @@ func checkExpiry(cert *x509.Certificate, it time.Time) error {
return nil
}

func VerifyBundle(sig oci.Signature) (bool, error) {
func VerifyBundle(ctx context.Context, sig oci.Signature) (bool, error) {
bundle, err := sig.Bundle()
if err != nil {
return false, err
} else if bundle == nil {
return false, nil
}

rekorPubKey, err := PemToECDSAKey([]byte(GetRekorPub()))
rekorPubKey, err := PemToECDSAKey([]byte(GetRekorPub(ctx)))
if err != nil {
return false, errors.Wrap(err, "pem to ecdsa")
}
Expand Down

0 comments on commit 6fc942b

Please sign in to comment.