Skip to content

Commit

Permalink
feat: support keyless verification for verify-blob-attestation
Browse files Browse the repository at this point in the history
Signed-off-by: Asra Ali <asraa@google.com>

fix

Signed-off-by: Asra Ali <asraa@google.com>

fix failure

Signed-off-by: Asra Ali <asraa@google.com>

fix windows

Signed-off-by: Asra Ali <asraa@google.com>

update cli options

Signed-off-by: Asra Ali <asraa@google.com>

docgen

Signed-off-by: Asra Ali <asraa@google.com>

add close

Signed-off-by: Asra Ali <asraa@google.com>
  • Loading branch information
asraa committed Dec 27, 2022
1 parent 7a9e4c7 commit dfebeda
Show file tree
Hide file tree
Showing 10 changed files with 441 additions and 244 deletions.
25 changes: 23 additions & 2 deletions cmd/cosign/cli/options/verify.go
Original file line number Diff line number Diff line change
Expand Up @@ -141,7 +141,6 @@ type VerifyBlobOptions struct {
SecurityKey SecurityKeyOptions
CertVerify CertVerifyOptions
Rekor RekorOptions
Registry RegistryOptions
CommonVerifyOptions CommonVerifyOptions

RFC3161TimestampPath string
Expand All @@ -154,7 +153,6 @@ func (o *VerifyBlobOptions) AddFlags(cmd *cobra.Command) {
o.SecurityKey.AddFlags(cmd)
o.Rekor.AddFlags(cmd)
o.CertVerify.AddFlags(cmd)
o.Registry.AddFlags(cmd)
o.CommonVerifyOptions.AddFlags(cmd)

cmd.Flags().StringVar(&o.Key, "key", "",
Expand Down Expand Up @@ -190,18 +188,41 @@ func (o *VerifyDockerfileOptions) AddFlags(cmd *cobra.Command) {
type VerifyBlobAttestationOptions struct {
Key string
SignaturePath string
BundlePath string

PredicateOptions
CheckClaims bool

SecurityKey SecurityKeyOptions
CertVerify CertVerifyOptions
Rekor RekorOptions
CommonVerifyOptions CommonVerifyOptions

RFC3161TimestampPath string
}

var _ Interface = (*VerifyBlobOptions)(nil)

// AddFlags implements Interface
func (o *VerifyBlobAttestationOptions) AddFlags(cmd *cobra.Command) {
o.PredicateOptions.AddFlags(cmd)
o.SecurityKey.AddFlags(cmd)
o.Rekor.AddFlags(cmd)
o.CertVerify.AddFlags(cmd)
o.CommonVerifyOptions.AddFlags(cmd)

cmd.Flags().StringVar(&o.Key, "key", "",
"path to the public key file, KMS URI or Kubernetes Secret")

cmd.Flags().StringVar(&o.SignaturePath, "signature", "",
"path to base64-encoded signature over attestation in DSSE format")

cmd.Flags().StringVar(&o.BundlePath, "bundle", "",
"path to bundle FILE")

cmd.Flags().BoolVar(&o.CheckClaims, "check-claims", true,
"whether to check the claims found")

cmd.Flags().StringVar(&o.RFC3161TimestampPath, "rfc3161-timestamp", "",
"path to RFC3161 timestamp FILE")
}
28 changes: 25 additions & 3 deletions cmd/cosign/cli/verify.go
Original file line number Diff line number Diff line change
Expand Up @@ -329,10 +329,32 @@ The blob may be specified as a path to a file.`,
Args: cobra.ExactArgs(1),
PersistentPreRun: options.BindViper,
RunE: func(cmd *cobra.Command, args []string) error {
ko := options.KeyOpts{
KeyRef: o.Key,
Sk: o.SecurityKey.Use,
Slot: o.SecurityKey.Slot,
RekorURL: o.Rekor.URL,
BundlePath: o.BundlePath,
RFC3161TimestampPath: o.RFC3161TimestampPath,
TSACertChainPath: o.CommonVerifyOptions.TSACertChainPath,
}
v := verify.VerifyBlobAttestationCommand{
KeyRef: o.Key,
PredicateType: o.PredicateOptions.Type,
SignaturePath: o.SignaturePath,
KeyOpts: ko,
PredicateType: o.PredicateOptions.Type,
CheckClaims: o.CheckClaims,
SignaturePath: o.SignaturePath,
CertVerifyOptions: o.CertVerify,
CertRef: o.CertVerify.Cert,
CertChain: o.CertVerify.CertChain,
CertGithubWorkflowTrigger: o.CertVerify.CertGithubWorkflowTrigger,
CertGithubWorkflowSHA: o.CertVerify.CertGithubWorkflowSha,
CertGithubWorkflowName: o.CertVerify.CertGithubWorkflowName,
CertGithubWorkflowRepository: o.CertVerify.CertGithubWorkflowRepository,
CertGithubWorkflowRef: o.CertVerify.CertGithubWorkflowRef,
IgnoreSCT: o.CertVerify.IgnoreSCT,
SCTRef: o.CertVerify.SCT,
Offline: o.CommonVerifyOptions.Offline,
SkipTlogVerify: o.CommonVerifyOptions.SkipTlogVerify,
}
if len(args) != 1 {
return fmt.Errorf("no path to blob passed in, run `cosign verify-blob-attestation -h` for more help")
Expand Down
45 changes: 6 additions & 39 deletions cmd/cosign/cli/verify/verify_blob.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,6 @@ import (
"os"
"path/filepath"

ssldsse "github.com/secure-systems-lab/go-securesystemslib/dsse"
"github.com/sigstore/cosign/v2/cmd/cosign/cli/fulcio"
"github.com/sigstore/cosign/v2/cmd/cosign/cli/options"
"github.com/sigstore/cosign/v2/cmd/cosign/cli/rekor"
Expand All @@ -40,7 +39,6 @@ import (
"github.com/sigstore/cosign/v2/pkg/oci/static"
sigs "github.com/sigstore/cosign/v2/pkg/signature"

ctypes "github.com/sigstore/cosign/v2/pkg/types"
"github.com/sigstore/sigstore/pkg/cryptoutils"
)

Expand Down Expand Up @@ -288,30 +286,12 @@ func (c *VerifyBlobCmd) Exec(ctx context.Context, blobRef string) error {
}
}

// Use the DSSE verifier if the payload is a DSSE with the In-Toto format.
// TODO: This verifier only supports verification of a single signer/signature on
// the envelope. Either have the verifier validate that only one signature exists,
// or use a multi-signature verifier.
if isIntotoDSSE(blobBytes) {
// co.SigVerifier = dsse.WrapVerifier(co.SigVerifier)
signature, err := static.NewAttestation(blobBytes, opts...)
if err != nil {
return err
}
// We have no artifact the attestation is tied to, so we can't do any claim
// verification.
// TODO: Add an option to support this to populate the v1.Hash for a claim.
if _, err = cosign.VerifyBlobAttestation(ctx, signature, co); err != nil {
return err
}
} else {
signature, err := static.NewSignature(blobBytes, sig, opts...)
if err != nil {
return err
}
if _, err = cosign.VerifyBlobSignature(ctx, signature, co); err != nil {
return err
}
signature, err := static.NewSignature(blobBytes, sig, opts...)
if err != nil {
return err
}
if _, err = cosign.VerifyBlobSignature(ctx, signature, co); err != nil {
return err
}

fmt.Fprintln(os.Stderr, "Verified OK")
Expand Down Expand Up @@ -361,16 +341,3 @@ func payloadBytes(blobRef string) ([]byte, error) {
}
return blobBytes, nil
}

// isIntotoDSSE checks whether a payload is a Dead Simple Signing Envelope with the In-Toto format.
func isIntotoDSSE(blobBytes []byte) bool {
DSSEenvelope := ssldsse.Envelope{}
if err := json.Unmarshal(blobBytes, &DSSEenvelope); err != nil {
return false
}
if DSSEenvelope.PayloadType != ctypes.IntotoPayloadType {
return false
}

return true
}
Loading

0 comments on commit dfebeda

Please sign in to comment.