From e46ca6af72bf80babf4e1c66462b64bc29ba747c Mon Sep 17 00:00:00 2001 From: Ville Aikas Date: Thu, 9 Jun 2022 11:28:42 +0300 Subject: [PATCH 1/2] Just chop chop chopping... Signed-off-by: Ville Aikas --- cmd/cosign/cli/attach.go | 99 ---- cmd/cosign/cli/attach/attestation.go | 92 ---- cmd/cosign/cli/attach/sbom.go | 75 --- cmd/cosign/cli/attach/sig.go | 125 ----- cmd/cosign/cli/attest.go | 91 ---- cmd/cosign/cli/attest/attest.go | 201 ------- cmd/cosign/cli/clean.go | 127 ----- cmd/cosign/cli/commands.go | 127 ----- cmd/cosign/cli/completion.go | 71 --- cmd/cosign/cli/copy.go | 50 -- cmd/cosign/cli/copy/copy.go | 156 ------ cmd/cosign/cli/dockerfile.go | 112 ---- cmd/cosign/cli/dockerfile/verify.go | 96 ---- cmd/cosign/cli/dockerfile/verify_test.go | 105 ---- cmd/cosign/cli/download.go | 97 ---- cmd/cosign/cli/download/attestation.go | 49 -- cmd/cosign/cli/download/sbom.go | 68 --- cmd/cosign/cli/download/signature.go | 49 -- cmd/cosign/cli/generate.go | 57 -- cmd/cosign/cli/generate/generate.go | 54 -- cmd/cosign/cli/generate/generate_key_pair.go | 136 ----- .../cli/generate/generate_key_pair_test.go | 47 -- cmd/cosign/cli/generate_key_pair.go | 72 --- cmd/cosign/cli/import_key_pair.go | 48 -- cmd/cosign/cli/initialize.go | 61 --- cmd/cosign/cli/initialize/init.go | 54 -- cmd/cosign/cli/load.go | 59 -- cmd/cosign/cli/manifest.go | 106 ---- cmd/cosign/cli/manifest/verify.go | 159 ------ cmd/cosign/cli/manifest/verify_test.go | 284 ---------- cmd/cosign/cli/options/attach.go | 117 ---- cmd/cosign/cli/options/attest.go | 74 --- cmd/cosign/cli/options/clean.go | 31 -- cmd/cosign/cli/options/copy.go | 40 -- cmd/cosign/cli/options/flags.go | 36 -- cmd/cosign/cli/options/flags_test.go | 84 --- cmd/cosign/cli/options/generate.go | 34 -- cmd/cosign/cli/options/generate_key_pair.go | 34 -- cmd/cosign/cli/options/import_key_pair.go | 34 -- cmd/cosign/cli/options/load.go | 34 -- cmd/cosign/cli/options/oidc.go | 72 --- cmd/cosign/cli/options/piv_tool.go | 138 ----- cmd/cosign/cli/options/pkcs11_tool.go | 54 -- cmd/cosign/cli/options/policy.go | 82 --- cmd/cosign/cli/options/public_key.go | 40 -- cmd/cosign/cli/options/registry.go | 99 ---- cmd/cosign/cli/options/security_key.go | 37 -- cmd/cosign/cli/options/sign.go | 87 --- cmd/cosign/cli/options/signblob.go | 65 --- cmd/cosign/cli/options/tree.go | 28 - cmd/cosign/cli/options/triangulate.go | 36 -- cmd/cosign/cli/options/upload.go | 55 -- cmd/cosign/cli/options/verify.go | 155 ------ cmd/cosign/cli/piv_tool.go | 180 ------- cmd/cosign/cli/piv_tool_disabled.go | 29 - cmd/cosign/cli/pivcli/commands.go | 355 ------------- cmd/cosign/cli/pkcs11_tool.go | 80 --- cmd/cosign/cli/pkcs11_tool_disabled.go | 29 - cmd/cosign/cli/pkcs11cli/commands.go | 245 --------- cmd/cosign/cli/policy_init.go | 304 ----------- cmd/cosign/cli/policy_init_test.go | 33 -- cmd/cosign/cli/public_key.go | 92 ---- cmd/cosign/cli/rekor/rekor.go | 30 -- cmd/cosign/cli/rekor/rekor_test.go | 52 -- cmd/cosign/cli/save.go | 76 --- cmd/cosign/cli/sign.go | 116 ---- cmd/cosign/cli/sign/sign.go | 502 ------------------ cmd/cosign/cli/sign/sign_blob.go | 129 ----- cmd/cosign/cli/sign/sign_test.go | 206 ------- cmd/cosign/cli/signblob.go | 102 ---- cmd/cosign/cli/tree.go | 155 ------ cmd/cosign/cli/triangulate.go | 44 -- cmd/cosign/cli/triangulate/triangulate.go | 56 -- cmd/cosign/cli/upload.go | 98 ---- cmd/cosign/cli/upload/blob.go | 60 --- cmd/cosign/cli/upload/wasm.go | 46 -- cmd/cosign/cli/verify.go | 270 ---------- cmd/cosign/cli/verify/verify.go | 336 ------------ cmd/cosign/cli/verify/verify_attestation.go | 237 --------- cmd/cosign/cli/verify/verify_blob.go | 452 ---------------- cmd/cosign/cli/verify/verify_blob_test.go | 143 ----- cmd/cosign/main.go | 54 -- cmd/fig/fig.go | 27 - cmd/help/main.go | 42 -- cmd/help/verify.sh | 25 - cmd/schema/main.go | 4 +- cmd/sget/cli/commands.go | 84 --- cmd/sget/cli/options/root.go | 39 -- cmd/sget/main.go | 55 -- doc/cosign.md | 45 -- doc/cosign_attach.md | 26 - doc/cosign_attach_attestation.md | 37 -- doc/cosign_attach_sbom.md | 39 -- doc/cosign_attach_signature.md | 38 -- doc/cosign_attest.md | 80 --- doc/cosign_clean.md | 38 -- doc/cosign_completion.md | 55 -- doc/cosign_copy.md | 47 -- doc/cosign_dockerfile.md | 24 - doc/cosign_dockerfile_verify.md | 90 ---- doc/cosign_download.md | 26 - doc/cosign_download_attestation.md | 36 -- doc/cosign_download_sbom.md | 36 -- doc/cosign_download_signature.md | 36 -- doc/cosign_generate-key-pair.md | 69 --- doc/cosign_generate.md | 52 -- doc/cosign_import-key-pair.md | 45 -- doc/cosign_initialize.md | 60 --- doc/cosign_load.md | 38 -- doc/cosign_login.md | 37 -- doc/cosign_manifest.md | 24 - doc/cosign_manifest_verify.md | 84 --- doc/cosign_piv-tool.md | 31 -- doc/cosign_piv-tool_attestation.md | 30 -- doc/cosign_piv-tool_generate-key.md | 33 -- doc/cosign_piv-tool_reset.md | 28 - doc/cosign_piv-tool_set-management-key.md | 31 -- doc/cosign_piv-tool_set-pin.md | 30 -- doc/cosign_piv-tool_set-puk.md | 30 -- doc/cosign_piv-tool_unblock.md | 30 -- doc/cosign_pkcs11-tool.md | 26 - doc/cosign_pkcs11-tool_list-keys-uris.md | 31 -- doc/cosign_pkcs11-tool_list-tokens.md | 29 - doc/cosign_policy.md | 35 -- doc/cosign_policy_init.md | 50 -- doc/cosign_policy_sign.md | 47 -- doc/cosign_public-key.md | 65 --- doc/cosign_save.md | 38 -- doc/cosign_sign-blob.md | 71 --- doc/cosign_sign.md | 98 ---- doc/cosign_tree.md | 36 -- doc/cosign_triangulate.md | 37 -- doc/cosign_upload.md | 25 - doc/cosign_upload_blob.md | 50 -- doc/cosign_upload_wasm.md | 37 -- doc/cosign_verify-attestation.md | 94 ---- doc/cosign_verify-blob.md | 93 ---- doc/cosign_verify.md | 103 ---- doc/cosign_version.md | 28 - go.mod | 11 +- go.sum | 7 - pkg/sget/sget.go | 130 ----- specs/ATTESTATION_SPEC.md | 54 -- specs/COSIGN_PREDICATE_SPEC.md | 31 -- specs/COSIGN_VULN_ATTESTATION_SPEC.md | 431 --------------- specs/SBOM_SPEC.md | 143 ----- specs/SIGNATURE_SPEC.md | 399 -------------- .../cpuguy83/go-md2man/v2/md2man/LICENSE.md | 21 - .../russross/blackfriday/v2/LICENSE.txt | 29 - .../autocomplete-tools/packages/cobra/LICENSE | 21 - 150 files changed, 7 insertions(+), 12748 deletions(-) delete mode 100644 cmd/cosign/cli/attach.go delete mode 100644 cmd/cosign/cli/attach/attestation.go delete mode 100644 cmd/cosign/cli/attach/sbom.go delete mode 100644 cmd/cosign/cli/attach/sig.go delete mode 100644 cmd/cosign/cli/attest.go delete mode 100644 cmd/cosign/cli/attest/attest.go delete mode 100644 cmd/cosign/cli/clean.go delete mode 100644 cmd/cosign/cli/commands.go delete mode 100644 cmd/cosign/cli/completion.go delete mode 100644 cmd/cosign/cli/copy.go delete mode 100644 cmd/cosign/cli/copy/copy.go delete mode 100644 cmd/cosign/cli/dockerfile.go delete mode 100644 cmd/cosign/cli/dockerfile/verify.go delete mode 100644 cmd/cosign/cli/dockerfile/verify_test.go delete mode 100644 cmd/cosign/cli/download.go delete mode 100644 cmd/cosign/cli/download/attestation.go delete mode 100644 cmd/cosign/cli/download/sbom.go delete mode 100644 cmd/cosign/cli/download/signature.go delete mode 100644 cmd/cosign/cli/generate.go delete mode 100644 cmd/cosign/cli/generate/generate.go delete mode 100644 cmd/cosign/cli/generate/generate_key_pair.go delete mode 100644 cmd/cosign/cli/generate/generate_key_pair_test.go delete mode 100644 cmd/cosign/cli/generate_key_pair.go delete mode 100644 cmd/cosign/cli/import_key_pair.go delete mode 100644 cmd/cosign/cli/initialize.go delete mode 100644 cmd/cosign/cli/initialize/init.go delete mode 100644 cmd/cosign/cli/load.go delete mode 100644 cmd/cosign/cli/manifest.go delete mode 100644 cmd/cosign/cli/manifest/verify.go delete mode 100644 cmd/cosign/cli/manifest/verify_test.go delete mode 100644 cmd/cosign/cli/options/attach.go delete mode 100644 cmd/cosign/cli/options/attest.go delete mode 100644 cmd/cosign/cli/options/clean.go delete mode 100644 cmd/cosign/cli/options/copy.go delete mode 100644 cmd/cosign/cli/options/flags.go delete mode 100644 cmd/cosign/cli/options/flags_test.go delete mode 100644 cmd/cosign/cli/options/generate.go delete mode 100644 cmd/cosign/cli/options/generate_key_pair.go delete mode 100644 cmd/cosign/cli/options/import_key_pair.go delete mode 100644 cmd/cosign/cli/options/load.go delete mode 100644 cmd/cosign/cli/options/oidc.go delete mode 100644 cmd/cosign/cli/options/piv_tool.go delete mode 100644 cmd/cosign/cli/options/pkcs11_tool.go delete mode 100644 cmd/cosign/cli/options/policy.go delete mode 100644 cmd/cosign/cli/options/public_key.go delete mode 100644 cmd/cosign/cli/options/registry.go delete mode 100644 cmd/cosign/cli/options/security_key.go delete mode 100644 cmd/cosign/cli/options/sign.go delete mode 100644 cmd/cosign/cli/options/signblob.go delete mode 100644 cmd/cosign/cli/options/tree.go delete mode 100644 cmd/cosign/cli/options/triangulate.go delete mode 100644 cmd/cosign/cli/options/upload.go delete mode 100644 cmd/cosign/cli/options/verify.go delete mode 100644 cmd/cosign/cli/piv_tool.go delete mode 100644 cmd/cosign/cli/piv_tool_disabled.go delete mode 100644 cmd/cosign/cli/pivcli/commands.go delete mode 100644 cmd/cosign/cli/pkcs11_tool.go delete mode 100644 cmd/cosign/cli/pkcs11_tool_disabled.go delete mode 100644 cmd/cosign/cli/pkcs11cli/commands.go delete mode 100644 cmd/cosign/cli/policy_init.go delete mode 100644 cmd/cosign/cli/policy_init_test.go delete mode 100644 cmd/cosign/cli/public_key.go delete mode 100644 cmd/cosign/cli/rekor/rekor.go delete mode 100644 cmd/cosign/cli/rekor/rekor_test.go delete mode 100644 cmd/cosign/cli/save.go delete mode 100644 cmd/cosign/cli/sign.go delete mode 100644 cmd/cosign/cli/sign/sign.go delete mode 100644 cmd/cosign/cli/sign/sign_blob.go delete mode 100644 cmd/cosign/cli/sign/sign_test.go delete mode 100644 cmd/cosign/cli/signblob.go delete mode 100644 cmd/cosign/cli/tree.go delete mode 100644 cmd/cosign/cli/triangulate.go delete mode 100644 cmd/cosign/cli/triangulate/triangulate.go delete mode 100644 cmd/cosign/cli/upload.go delete mode 100644 cmd/cosign/cli/upload/blob.go delete mode 100644 cmd/cosign/cli/upload/wasm.go delete mode 100644 cmd/cosign/cli/verify.go delete mode 100644 cmd/cosign/cli/verify/verify.go delete mode 100644 cmd/cosign/cli/verify/verify_attestation.go delete mode 100644 cmd/cosign/cli/verify/verify_blob.go delete mode 100644 cmd/cosign/cli/verify/verify_blob_test.go delete mode 100644 cmd/cosign/main.go delete mode 100644 cmd/fig/fig.go delete mode 100644 cmd/help/main.go delete mode 100755 cmd/help/verify.sh delete mode 100644 cmd/sget/cli/commands.go delete mode 100644 cmd/sget/cli/options/root.go delete mode 100644 cmd/sget/main.go delete mode 100644 doc/cosign.md delete mode 100644 doc/cosign_attach.md delete mode 100644 doc/cosign_attach_attestation.md delete mode 100644 doc/cosign_attach_sbom.md delete mode 100644 doc/cosign_attach_signature.md delete mode 100644 doc/cosign_attest.md delete mode 100644 doc/cosign_clean.md delete mode 100644 doc/cosign_completion.md delete mode 100644 doc/cosign_copy.md delete mode 100644 doc/cosign_dockerfile.md delete mode 100644 doc/cosign_dockerfile_verify.md delete mode 100644 doc/cosign_download.md delete mode 100644 doc/cosign_download_attestation.md delete mode 100644 doc/cosign_download_sbom.md delete mode 100644 doc/cosign_download_signature.md delete mode 100644 doc/cosign_generate-key-pair.md delete mode 100644 doc/cosign_generate.md delete mode 100644 doc/cosign_import-key-pair.md delete mode 100644 doc/cosign_initialize.md delete mode 100644 doc/cosign_load.md delete mode 100644 doc/cosign_login.md delete mode 100644 doc/cosign_manifest.md delete mode 100644 doc/cosign_manifest_verify.md delete mode 100644 doc/cosign_piv-tool.md delete mode 100644 doc/cosign_piv-tool_attestation.md delete mode 100644 doc/cosign_piv-tool_generate-key.md delete mode 100644 doc/cosign_piv-tool_reset.md delete mode 100644 doc/cosign_piv-tool_set-management-key.md delete mode 100644 doc/cosign_piv-tool_set-pin.md delete mode 100644 doc/cosign_piv-tool_set-puk.md delete mode 100644 doc/cosign_piv-tool_unblock.md delete mode 100644 doc/cosign_pkcs11-tool.md delete mode 100644 doc/cosign_pkcs11-tool_list-keys-uris.md delete mode 100644 doc/cosign_pkcs11-tool_list-tokens.md delete mode 100644 doc/cosign_policy.md delete mode 100644 doc/cosign_policy_init.md delete mode 100644 doc/cosign_policy_sign.md delete mode 100644 doc/cosign_public-key.md delete mode 100644 doc/cosign_save.md delete mode 100644 doc/cosign_sign-blob.md delete mode 100644 doc/cosign_sign.md delete mode 100644 doc/cosign_tree.md delete mode 100644 doc/cosign_triangulate.md delete mode 100644 doc/cosign_upload.md delete mode 100644 doc/cosign_upload_blob.md delete mode 100644 doc/cosign_upload_wasm.md delete mode 100644 doc/cosign_verify-attestation.md delete mode 100644 doc/cosign_verify-blob.md delete mode 100644 doc/cosign_verify.md delete mode 100644 doc/cosign_version.md delete mode 100644 pkg/sget/sget.go delete mode 100644 specs/ATTESTATION_SPEC.md delete mode 100644 specs/COSIGN_PREDICATE_SPEC.md delete mode 100644 specs/COSIGN_VULN_ATTESTATION_SPEC.md delete mode 100644 specs/SBOM_SPEC.md delete mode 100644 specs/SIGNATURE_SPEC.md delete mode 100644 third_party/VENDOR-LICENSE/github.com/cpuguy83/go-md2man/v2/md2man/LICENSE.md delete mode 100644 third_party/VENDOR-LICENSE/github.com/russross/blackfriday/v2/LICENSE.txt delete mode 100644 third_party/VENDOR-LICENSE/github.com/withfig/autocomplete-tools/packages/cobra/LICENSE diff --git a/cmd/cosign/cli/attach.go b/cmd/cosign/cli/attach.go deleted file mode 100644 index 7ba574045..000000000 --- a/cmd/cosign/cli/attach.go +++ /dev/null @@ -1,99 +0,0 @@ -// -// Copyright 2021 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 cli - -import ( - "fmt" - "os" - - "github.com/sigstore/policy-controller/cmd/cosign/cli/attach" - "github.com/sigstore/policy-controller/cmd/cosign/cli/options" - "github.com/spf13/cobra" -) - -func Attach() *cobra.Command { - cmd := &cobra.Command{ - Use: "attach", - Short: "Provides utilities for attaching artifacts to other artifacts in a registry", - } - - cmd.AddCommand( - attachSignature(), - attachSBOM(), - attachAttestation(), - ) - - return cmd -} - -func attachSignature() *cobra.Command { - o := &options.AttachSignatureOptions{} - - cmd := &cobra.Command{ - Use: "signature", - Short: "Attach signatures to the supplied container image", - Example: " cosign attach signature ", - Args: cobra.ExactArgs(1), - RunE: func(cmd *cobra.Command, args []string) error { - return attach.SignatureCmd(cmd.Context(), o.Registry, o.Signature, o.Payload, args[0]) - }, - } - - o.AddFlags(cmd) - - return cmd -} - -func attachSBOM() *cobra.Command { - o := &options.AttachSBOMOptions{} - - cmd := &cobra.Command{ - Use: "sbom", - Short: "Attach sbom to the supplied container image", - Example: " cosign attach sbom ", - Args: cobra.ExactArgs(1), - RunE: func(cmd *cobra.Command, args []string) error { - mediaType, err := o.MediaType() - if err != nil { - return err - } - fmt.Fprintf(os.Stderr, "WARNING: Attaching SBOMs this way does not sign them. If you want to sign them, use 'cosign attest -predicate %s -key ' or 'cosign sign -key '.\n", o.SBOM) - return attach.SBOMCmd(cmd.Context(), o.Registry, o.SBOM, mediaType, args[0]) - }, - } - - o.AddFlags(cmd) - - return cmd -} - -func attachAttestation() *cobra.Command { - o := &options.AttachAttestationOptions{} - - cmd := &cobra.Command{ - Use: "attestation", - Short: "Attach attestation to the supplied container image", - Example: " cosign attach attestation ", - Args: cobra.ExactArgs(1), - RunE: func(cmd *cobra.Command, args []string) error { - return attach.AttestationCmd(cmd.Context(), o.Registry, o.Attestation, args[0]) - }, - } - - o.AddFlags(cmd) - - return cmd -} diff --git a/cmd/cosign/cli/attach/attestation.go b/cmd/cosign/cli/attach/attestation.go deleted file mode 100644 index 902e5f53e..000000000 --- a/cmd/cosign/cli/attach/attestation.go +++ /dev/null @@ -1,92 +0,0 @@ -// Copyright 2021 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 attach - -import ( - "context" - "encoding/json" - "fmt" - "os" - - "github.com/google/go-containerregistry/pkg/name" - ssldsse "github.com/secure-systems-lab/go-securesystemslib/dsse" - "github.com/sigstore/policy-controller/cmd/cosign/cli/options" - "github.com/sigstore/policy-controller/pkg/oci/mutate" - ociremote "github.com/sigstore/policy-controller/pkg/oci/remote" - "github.com/sigstore/policy-controller/pkg/oci/static" - "github.com/sigstore/policy-controller/pkg/types" -) - -func AttestationCmd(ctx context.Context, regOpts options.RegistryOptions, signedPayload, imageRef string) error { - ociremoteOpts, err := regOpts.ClientOpts(ctx) - if err != nil { - return fmt.Errorf("constructing client options: %w", err) - } - - fmt.Fprintln(os.Stderr, "Using payload from:", signedPayload) - payload, err := os.ReadFile(signedPayload) - if err != nil { - return err - } - - if len(payload) == 0 { - return fmt.Errorf("%s payload is empty", signedPayload) - } - - env := ssldsse.Envelope{} - if err := json.Unmarshal(payload, &env); err != nil { - return err - } - - if env.PayloadType != types.IntotoPayloadType { - return fmt.Errorf("invalid payloadType %s on envelope. Expected %s", env.PayloadType, types.IntotoPayloadType) - } - - if len(env.Signatures) == 0 { - return fmt.Errorf("could not attach attestation without having signatures") - } - - ref, err := name.ParseReference(imageRef) - if err != nil { - return err - } - digest, err := ociremote.ResolveDigest(ref, ociremoteOpts...) - if err != nil { - return err - } - // Overwrite "ref" with a digest to avoid a race where we use a tag - // multiple times, and it potentially points to different things at - // each access. - ref = digest // nolint - - opts := []static.Option{static.WithLayerMediaType(types.DssePayloadType)} - att, err := static.NewAttestation(payload, opts...) - if err != nil { - return err - } - - se, err := ociremote.SignedEntity(digest, ociremoteOpts...) - if err != nil { - return err - } - - newSE, err := mutate.AttachAttestationToEntity(se, att) - if err != nil { - return err - } - - // Publish the signatures associated with this entity - return ociremote.WriteAttestations(digest.Repository, newSE, ociremoteOpts...) -} diff --git a/cmd/cosign/cli/attach/sbom.go b/cmd/cosign/cli/attach/sbom.go deleted file mode 100644 index cff7ef36f..000000000 --- a/cmd/cosign/cli/attach/sbom.go +++ /dev/null @@ -1,75 +0,0 @@ -// -// Copyright 2021 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 attach - -import ( - "context" - "errors" - "fmt" - "io" - "os" - "path/filepath" - - "github.com/google/go-containerregistry/pkg/name" - "github.com/google/go-containerregistry/pkg/v1/remote" - "github.com/google/go-containerregistry/pkg/v1/types" - "github.com/sigstore/policy-controller/cmd/cosign/cli/options" - ociremote "github.com/sigstore/policy-controller/pkg/oci/remote" - "github.com/sigstore/policy-controller/pkg/oci/static" -) - -func SBOMCmd(ctx context.Context, regOpts options.RegistryOptions, sbomRef string, sbomType types.MediaType, imageRef string) error { - ref, err := name.ParseReference(imageRef) - if err != nil { - return err - } - - b, err := sbomBytes(sbomRef) - if err != nil { - return err - } - - remoteOpts, err := regOpts.ClientOpts(ctx) - if err != nil { - return err - } - - dstRef, err := ociremote.SBOMTag(ref, remoteOpts...) - if err != nil { - return err - } - - fmt.Fprintf(os.Stderr, "Uploading SBOM file for [%s] to [%s] with mediaType [%s].\n", ref.Name(), dstRef.Name(), sbomType) - img, err := static.NewFile(b, static.WithLayerMediaType(sbomType)) - if err != nil { - return err - } - return remote.Write(dstRef, img, regOpts.GetRegistryClientOpts(ctx)...) -} - -func sbomBytes(sbomRef string) ([]byte, error) { - // sbomRef can be "-", a string or a file. - switch signatureType(sbomRef) { - case StdinSignature: - return io.ReadAll(os.Stdin) - case RawSignature: - return []byte(sbomRef), nil - case FileSignature: - return os.ReadFile(filepath.Clean(sbomRef)) - default: - return nil, errors.New("unknown SBOM arg type") - } -} diff --git a/cmd/cosign/cli/attach/sig.go b/cmd/cosign/cli/attach/sig.go deleted file mode 100644 index a0bf91974..000000000 --- a/cmd/cosign/cli/attach/sig.go +++ /dev/null @@ -1,125 +0,0 @@ -// -// Copyright 2021 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 attach - -import ( - "context" - "errors" - "io" - "os" - "path/filepath" - - "github.com/google/go-containerregistry/pkg/name" - - "github.com/sigstore/policy-controller/cmd/cosign/cli/options" - "github.com/sigstore/policy-controller/pkg/oci/mutate" - ociremote "github.com/sigstore/policy-controller/pkg/oci/remote" - "github.com/sigstore/policy-controller/pkg/oci/static" - sigPayload "github.com/sigstore/sigstore/pkg/signature/payload" -) - -func SignatureCmd(ctx context.Context, regOpts options.RegistryOptions, sigRef, payloadRef, imageRef string) error { - b64SigBytes, err := signatureBytes(sigRef) - if err != nil { - return err - } else if len(b64SigBytes) == 0 { - return errors.New("empty signature") - } - - ref, err := name.ParseReference(imageRef) - if err != nil { - return err - } - ociremoteOpts, err := regOpts.ClientOpts(ctx) - if err != nil { - return err - } - digest, err := ociremote.ResolveDigest(ref, ociremoteOpts...) - if err != nil { - return err - } - // Overwrite "ref" with a digest to avoid a race where we use a tag - // multiple times, and it potentially points to different things at - // each access. - ref = digest // nolint - - var payload []byte - if payloadRef == "" { - payload, err = (&sigPayload.Cosign{Image: digest}).MarshalJSON() - } else { - payload, err = os.ReadFile(filepath.Clean(payloadRef)) - } - if err != nil { - return err - } - - sig, err := static.NewSignature(payload, string(b64SigBytes)) - if err != nil { - return err - } - - se, err := ociremote.SignedEntity(digest, ociremoteOpts...) - if err != nil { - return err - } - - // Attach the signature to the entity. - newSE, err := mutate.AttachSignatureToEntity(se, sig) - if err != nil { - return err - } - - // Publish the signatures associated with this entity - return ociremote.WriteSignatures(digest.Repository, newSE, ociremoteOpts...) -} - -type SignatureArgType uint8 - -const ( - StdinSignature SignatureArgType = iota - RawSignature SignatureArgType = iota - FileSignature SignatureArgType = iota -) - -func signatureBytes(sigRef string) ([]byte, error) { - // sigRef can be "-", a string or a file. - switch signatureType(sigRef) { - case StdinSignature: - return io.ReadAll(os.Stdin) - case RawSignature: - return []byte(sigRef), nil - case FileSignature: - return os.ReadFile(filepath.Clean(sigRef)) - default: - return nil, errors.New("unknown signature arg type") - } -} - -func signatureType(sigRef string) SignatureArgType { - switch { - case sigRef == "-": - return StdinSignature - case signatureFileNotExists(sigRef): - return RawSignature - default: - return FileSignature - } -} - -func signatureFileNotExists(sigRef string) bool { - _, err := os.Stat(sigRef) - return os.IsNotExist(err) -} diff --git a/cmd/cosign/cli/attest.go b/cmd/cosign/cli/attest.go deleted file mode 100644 index 507edc91f..000000000 --- a/cmd/cosign/cli/attest.go +++ /dev/null @@ -1,91 +0,0 @@ -// -// Copyright 2021 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 cli - -import ( - "fmt" - - "github.com/spf13/cobra" - - "github.com/sigstore/policy-controller/cmd/cosign/cli/attest" - "github.com/sigstore/policy-controller/cmd/cosign/cli/generate" - "github.com/sigstore/policy-controller/cmd/cosign/cli/options" -) - -func Attest() *cobra.Command { - o := &options.AttestOptions{} - - cmd := &cobra.Command{ - Use: "attest", - Short: "Attest the supplied container image.", - Example: ` cosign attest --key | [--predicate ] [--a key=value] [--no-upload=true|false] [--f] [--r] - - # attach an attestation to a container image Google sign-in (experimental) - COSIGN_EXPERIMENTAL=1 cosign attest --timeout 90s --predicate --type - - # attach an attestation to a container image with a local key pair file - cosign attest --predicate --type --key cosign.key - - # attach an attestation to a container image with a key pair stored in Azure Key Vault - cosign attest --predicate --type --key azurekms://[VAULT_NAME][VAULT_URI]/[KEY] - - # attach an attestation to a container image with a key pair stored in AWS KMS - cosign attest --predicate --type --key awskms://[ENDPOINT]/[ID/ALIAS/ARN] - - # attach an attestation to a container image with a key pair stored in Google Cloud KMS - cosign attest --predicate --type --key gcpkms://projects/[PROJECT]/locations/global/keyRings/[KEYRING]/cryptoKeys/[KEY]/versions/[VERSION] - - # attach an attestation to a container image with a key pair stored in Hashicorp Vault - cosign attest --predicate --type --key hashivault://[KEY] - - # attach an attestation to a container image with a local key pair file, including a certificate and certificate chain - cosign attest --predicate --type --key cosign.key --cert cosign.crt --cert-chain chain.crt - - # attach an attestation to a container image which does not fully support OCI media types - COSIGN_DOCKER_MEDIA_TYPES=1 cosign attest --predicate --type --key cosign.key legacy-registry.example.com/my/image`, - - Args: cobra.MinimumNArgs(1), - RunE: func(cmd *cobra.Command, args []string) error { - oidcClientSecret, err := o.OIDC.ClientSecret() - if err != nil { - return err - } - ko := options.KeyOpts{ - KeyRef: o.Key, - PassFunc: generate.GetPass, - Sk: o.SecurityKey.Use, - Slot: o.SecurityKey.Slot, - FulcioURL: o.Fulcio.URL, - IDToken: o.Fulcio.IdentityToken, - InsecureSkipFulcioVerify: o.Fulcio.InsecureSkipFulcioVerify, - RekorURL: o.Rekor.URL, - OIDCIssuer: o.OIDC.Issuer, - OIDCClientID: o.OIDC.ClientID, - OIDCClientSecret: oidcClientSecret, - OIDCRedirectURL: o.OIDC.RedirectURL, - } - for _, img := range args { - if err := attest.AttestCmd(cmd.Context(), ko, o.Registry, img, o.Cert, o.CertChain, o.NoUpload, - o.Predicate.Path, o.Force, o.Predicate.Type, o.Replace, ro.Timeout); err != nil { - return fmt.Errorf("signing %s: %w", img, err) - } - } - return nil - }, - } - o.AddFlags(cmd) - return cmd -} diff --git a/cmd/cosign/cli/attest/attest.go b/cmd/cosign/cli/attest/attest.go deleted file mode 100644 index b07f7c3d1..000000000 --- a/cmd/cosign/cli/attest/attest.go +++ /dev/null @@ -1,201 +0,0 @@ -// -// Copyright 2021 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 attest - -import ( - "bytes" - "context" - _ "crypto/sha256" // for `crypto.SHA256` - "encoding/json" - "fmt" - "os" - "time" - - "github.com/google/go-containerregistry/pkg/name" - v1 "github.com/google/go-containerregistry/pkg/v1" - - "github.com/sigstore/policy-controller/cmd/cosign/cli/options" - "github.com/sigstore/policy-controller/cmd/cosign/cli/rekor" - "github.com/sigstore/policy-controller/cmd/cosign/cli/sign" - "github.com/sigstore/policy-controller/pkg/cosign" - "github.com/sigstore/policy-controller/pkg/cosign/attestation" - cbundle "github.com/sigstore/policy-controller/pkg/cosign/bundle" - cremote "github.com/sigstore/policy-controller/pkg/cosign/remote" - "github.com/sigstore/policy-controller/pkg/oci/mutate" - ociremote "github.com/sigstore/policy-controller/pkg/oci/remote" - "github.com/sigstore/policy-controller/pkg/oci/static" - sigs "github.com/sigstore/policy-controller/pkg/signature" - "github.com/sigstore/policy-controller/pkg/types" - "github.com/sigstore/rekor/pkg/generated/client" - "github.com/sigstore/rekor/pkg/generated/models" - "github.com/sigstore/sigstore/pkg/signature/dsse" - signatureoptions "github.com/sigstore/sigstore/pkg/signature/options" -) - -type tlogUploadFn func(*client.Rekor, []byte) (*models.LogEntryAnon, error) - -func uploadToTlog(ctx context.Context, sv *sign.SignerVerifier, rekorURL string, upload tlogUploadFn) (*cbundle.RekorBundle, error) { - var rekorBytes []byte - // Upload the cert or the public key, depending on what we have - if sv.Cert != nil { - rekorBytes = sv.Cert - } else { - pemBytes, err := sigs.PublicKeyPem(sv, signatureoptions.WithContext(ctx)) - if err != nil { - return nil, err - } - rekorBytes = pemBytes - } - - rekorClient, err := rekor.NewClient(rekorURL) - if err != nil { - return nil, err - } - entry, err := upload(rekorClient, rekorBytes) - if err != nil { - return nil, err - } - fmt.Fprintln(os.Stderr, "tlog entry created with index:", *entry.LogIndex) - return cbundle.EntryToBundle(entry), nil -} - -//nolint -func AttestCmd(ctx context.Context, ko options.KeyOpts, regOpts options.RegistryOptions, imageRef string, certPath string, certChainPath string, - noUpload bool, predicatePath string, force bool, predicateType string, replace bool, timeout time.Duration) error { - // A key file or token is required unless we're in experimental mode! - if options.EnableExperimental() { - if options.NOf(ko.KeyRef, ko.Sk) > 1 { - return &options.KeyParseError{} - } - } else { - if !options.OneOf(ko.KeyRef, ko.Sk) { - return &options.KeyParseError{} - } - } - - predicateURI, err := options.ParsePredicateType(predicateType) - if err != nil { - return err - } - - ref, err := name.ParseReference(imageRef) - if err != nil { - return fmt.Errorf("parsing reference: %w", err) - } - - 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 - } - digest, err := ociremote.ResolveDigest(ref, ociremoteOpts...) - if err != nil { - return err - } - h, _ := v1.NewHash(digest.Identifier()) - // Overwrite "ref" with a digest to avoid a race where we use a tag - // multiple times, and it potentially points to different things at - // each access. - ref = digest // nolint - - sv, err := sign.SignerFromKeyOpts(ctx, certPath, certChainPath, ko) - if err != nil { - return fmt.Errorf("getting signer: %w", err) - } - defer sv.Close() - wrapped := dsse.WrapSigner(sv, types.IntotoPayloadType) - dd := cremote.NewDupeDetector(sv) - - fmt.Fprintln(os.Stderr, "Using payload from:", predicatePath) - predicate, err := os.Open(predicatePath) - if err != nil { - return err - } - defer predicate.Close() - - sh, err := attestation.GenerateStatement(attestation.GenerateOpts{ - Predicate: predicate, - Type: predicateType, - Digest: h.Hex, - Repo: digest.Repository.String(), - }) - if err != nil { - return err - } - - payload, err := json.Marshal(sh) - if err != nil { - return err - } - signedPayload, err := wrapped.SignMessage(bytes.NewReader(payload), signatureoptions.WithContext(ctx)) - if err != nil { - return fmt.Errorf("signing: %w", err) - } - - if noUpload { - fmt.Println(string(signedPayload)) - return nil - } - - opts := []static.Option{static.WithLayerMediaType(types.DssePayloadType)} - if sv.Cert != nil { - opts = append(opts, static.WithCertChain(sv.Cert, sv.Chain)) - } - - // Check whether we should be uploading to the transparency log - if sign.ShouldUploadToTlog(ctx, digest, force, ko.RekorURL) { - bundle, err := uploadToTlog(ctx, sv, ko.RekorURL, func(r *client.Rekor, b []byte) (*models.LogEntryAnon, error) { - return cosign.TLogUploadInTotoAttestation(ctx, r, signedPayload, b) - }) - if err != nil { - return err - } - opts = append(opts, static.WithBundle(bundle)) - } - - sig, err := static.NewAttestation(signedPayload, opts...) - if err != nil { - return err - } - - se, err := ociremote.SignedEntity(digest, ociremoteOpts...) - if err != nil { - return err - } - - signOpts := []mutate.SignOption{ - mutate.WithDupeDetector(dd), - } - - if replace { - ro := cremote.NewReplaceOp(predicateURI) - signOpts = append(signOpts, mutate.WithReplaceOp(ro)) - } - - // Attach the attestation to the entity. - newSE, err := mutate.AttachAttestationToEntity(se, sig, signOpts...) - if err != nil { - return err - } - - // Publish the attestations associated with this entity - return ociremote.WriteAttestations(digest.Repository, newSE, ociremoteOpts...) -} diff --git a/cmd/cosign/cli/clean.go b/cmd/cosign/cli/clean.go deleted file mode 100644 index 3e6243f8f..000000000 --- a/cmd/cosign/cli/clean.go +++ /dev/null @@ -1,127 +0,0 @@ -// -// Copyright 2021 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 cli - -import ( - "context" - "errors" - "fmt" - "net/http" - "os" - - "github.com/google/go-containerregistry/pkg/name" - "github.com/google/go-containerregistry/pkg/v1/remote" - "github.com/google/go-containerregistry/pkg/v1/remote/transport" - "github.com/spf13/cobra" - - "github.com/sigstore/policy-controller/cmd/cosign/cli/options" - "github.com/sigstore/policy-controller/pkg/cosign" - ociremote "github.com/sigstore/policy-controller/pkg/oci/remote" -) - -func Clean() *cobra.Command { - c := &options.CleanOptions{} - - cmd := &cobra.Command{ - Use: "clean", - Short: "Remove all signatures from an image.", - Example: " cosign clean ", - Args: cobra.ExactArgs(1), - RunE: func(cmd *cobra.Command, args []string) error { - return CleanCmd(cmd.Context(), c.Registry, c.CleanType, args[0], c.Force) - }, - } - - c.AddFlags(cmd) - return cmd -} - -func CleanCmd(ctx context.Context, regOpts options.RegistryOptions, cleanType, imageRef string, force bool) error { - if !force { - ok, err := cosign.ConfirmPromptDestructive(prompt(cleanType)) - if err != nil { - return err - } - if !ok { - return nil - } - } - - ref, err := name.ParseReference(imageRef) - if err != nil { - return err - } - - remoteOpts := regOpts.GetRegistryClientOpts(ctx) - - sigRef, err := ociremote.SignatureTag(ref, ociremote.WithRemoteOptions(remoteOpts...)) - if err != nil { - return err - } - - attRef, err := ociremote.AttestationTag(ref, ociremote.WithRemoteOptions(remoteOpts...)) - if err != nil { - return err - } - - sbomRef, err := ociremote.SBOMTag(ref, ociremote.WithRemoteOptions(remoteOpts...)) - if err != nil { - return err - } - - var cleanTags []name.Tag - switch cleanType { - case "signature": - cleanTags = []name.Tag{sigRef} - case "sbom": - cleanTags = []name.Tag{sbomRef} - case "attestation": - cleanTags = []name.Tag{attRef} - case "all": - cleanTags = []name.Tag{sigRef, attRef, sbomRef} - } - - for _, t := range cleanTags { - if err := remote.Delete(t, remoteOpts...); err != nil { - var te *transport.Error - if errors.As(err, &te) && te.StatusCode == http.StatusNotFound { - // If the tag doesn't exist, some registries may - // respond with a 404, which shouldn't be considered an - // error. - } else { - fmt.Fprintf(os.Stderr, "could not delete %s from %s\n: %v\n", t, imageRef, err) - } - } else { - fmt.Fprintf(os.Stderr, "Removed %s from %s\n", t, imageRef) - } - } - - return nil -} - -func prompt(cleanType string) string { - switch cleanType { - case "signature": - return "WARNING: this will remove all signatures from the image" - case "sbom": - return "WARNING: this will remove all SBOMs from the image" - case "attestation": - return "WARNING: this will remove all attestations from the image" - case "all": - return "WARNING: this will remove all signatures, SBOMs and attestations from the image" - } - return "" -} diff --git a/cmd/cosign/cli/commands.go b/cmd/cosign/cli/commands.go deleted file mode 100644 index 0bf2b28b9..000000000 --- a/cmd/cosign/cli/commands.go +++ /dev/null @@ -1,127 +0,0 @@ -// -// Copyright 2021 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 cli - -import ( - "fmt" - "os" - - "github.com/google/go-containerregistry/pkg/logs" - "github.com/spf13/cobra" - "github.com/spf13/pflag" - "sigs.k8s.io/release-utils/version" - - cranecmd "github.com/google/go-containerregistry/cmd/crane/cmd" - "github.com/sigstore/policy-controller/cmd/cosign/cli/options" - "github.com/sigstore/policy-controller/pkg/cosign" -) - -var ( - ro = &options.RootOptions{} -) - -func normalizeCertificateFlags(_ *pflag.FlagSet, name string) pflag.NormalizedName { - switch name { - case "cert": - name = "certificate" - case "cert-email": - name = "certificate-email" - case "cert-chain": - name = "certificate-chain" - case "cert-oidc-issuer": - name = "certificate-oidc-issuer" - case "output-cert": - name = "output-certificate" - } - return pflag.NormalizedName(name) -} - -func New() *cobra.Command { - var ( - out, stdout *os.File - ) - - cmd := &cobra.Command{ - Use: "cosign", - Short: "A tool for Container Signing, Verification and Storage in an OCI registry.", - DisableAutoGenTag: true, - SilenceUsage: true, // Don't show usage on errors - PersistentPreRunE: func(cmd *cobra.Command, args []string) error { - if ro.OutputFile != "" { - var err error - out, err = os.Create(ro.OutputFile) - if err != nil { - return fmt.Errorf("error creating output file %s: %w", ro.OutputFile, err) - } - stdout = os.Stdout - os.Stdout = out // TODO: don't do this. - cmd.SetOut(out) - } - - if ro.Verbose { - logs.Debug.SetOutput(os.Stderr) - } - - if ro.SkipConfirmation { - cosign.SetSkipConfirmation(ro.SkipConfirmation) - } - - return nil - }, - PersistentPostRun: func(cmd *cobra.Command, args []string) { - if out != nil { - _ = out.Close() - } - os.Stdout = stdout - }, - } - ro.AddFlags(cmd) - - // Add sub-commands. - cmd.AddCommand(Attach()) - cmd.AddCommand(Attest()) - cmd.AddCommand(Clean()) - cmd.AddCommand(Tree()) - cmd.AddCommand(Completion()) - cmd.AddCommand(Copy()) - cmd.AddCommand(Dockerfile()) - cmd.AddCommand(Download()) - cmd.AddCommand(Generate()) - cmd.AddCommand(GenerateKeyPair()) - cmd.AddCommand(ImportKeyPair()) - cmd.AddCommand(Initialize()) - cmd.AddCommand(Load()) - cmd.AddCommand(Manifest()) - cmd.AddCommand(PIVTool()) - cmd.AddCommand(PKCS11Tool()) - cmd.AddCommand(Policy()) - cmd.AddCommand(PublicKey()) - cmd.AddCommand(Save()) - cmd.AddCommand(Sign()) - cmd.AddCommand(SignBlob()) - cmd.AddCommand(Upload()) - cmd.AddCommand(Verify()) - cmd.AddCommand(VerifyAttestation()) - cmd.AddCommand(VerifyBlob()) - cmd.AddCommand(Triangulate()) - cmd.AddCommand(version.WithFont("starwars")) - - cmd.AddCommand(cranecmd.NewCmdAuthLogin("cosign")) - - cmd.SetGlobalNormalizationFunc(normalizeCertificateFlags) - - return cmd -} diff --git a/cmd/cosign/cli/completion.go b/cmd/cosign/cli/completion.go deleted file mode 100644 index ce371623d..000000000 --- a/cmd/cosign/cli/completion.go +++ /dev/null @@ -1,71 +0,0 @@ -// -// Copyright 2021 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 cli - -import ( - "os" - - "github.com/spf13/cobra" -) - -func Completion() *cobra.Command { - completionCmd := &cobra.Command{ - Use: "completion [bash|zsh|fish|powershell]", - Short: "Generate completion script", - Long: `To load completions: -Bash: - $ source <(cosign completion bash) - # To load completions for each session, execute once: - # Linux: - $ cosign completion bash > /etc/bash_completion.d/cosign - # macOS: - $ cosign completion bash > /usr/local/etc/bash_completion.d/cosign -Zsh: - # If shell completion is not already enabled in your environment, - # you will need to enable it. You can execute the following once: - $ echo "autoload -U compinit; compinit" >> ~/.zshrc - # To load completions for each session, execute once: - $ cosign completion zsh > "${fpath[1]}/_cosign" - # You will need to start a new shell for this setup to take effect. -fish: - $ cosign completion fish | source - # To load completions for each session, execute once: - $ cosign completion fish > ~/.config/fish/completions/cosign.fish -PowerShell: - PS> cosign completion powershell | Out-String | Invoke-Expression - # To load completions for every new session, run: - PS> cosign completion powershell > cosign.ps1 - # and source this file from your PowerShell profile. -`, - DisableFlagsInUseLine: true, - ValidArgs: []string{"bash", "zsh", "fish", "powershell"}, - Args: cobra.ExactValidArgs(1), - Run: func(cmd *cobra.Command, args []string) { - switch args[0] { - case "bash": - _ = cmd.Root().GenBashCompletion(os.Stdout) - case "zsh": - _ = cmd.Root().GenZshCompletion(os.Stdout) - case "fish": - _ = cmd.Root().GenFishCompletion(os.Stdout, true) - case "powershell": - _ = cmd.Root().GenPowerShellCompletionWithDesc(os.Stdout) - } - }, - } - - return completionCmd -} diff --git a/cmd/cosign/cli/copy.go b/cmd/cosign/cli/copy.go deleted file mode 100644 index 58de74ee4..000000000 --- a/cmd/cosign/cli/copy.go +++ /dev/null @@ -1,50 +0,0 @@ -// -// Copyright 2021 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 cli - -import ( - "github.com/spf13/cobra" - - "github.com/sigstore/policy-controller/cmd/cosign/cli/copy" - "github.com/sigstore/policy-controller/cmd/cosign/cli/options" -) - -func Copy() *cobra.Command { - o := &options.CopyOptions{} - - cmd := &cobra.Command{ - Use: "copy", - Short: "Copy the supplied container image and signatures.", - Example: ` cosign copy - - # copy a container image and its signatures - cosign copy example.com/src:latest example.com/dest:latest - - # copy the signatures only - cosign copy --sig-only example.com/src example.com/dest - - # overwrite destination image and signatures - cosign copy -f example.com/src example.com/dest`, - - Args: cobra.ExactArgs(2), - RunE: func(cmd *cobra.Command, args []string) error { - return copy.CopyCmd(cmd.Context(), o.Registry, args[0], args[1], o.SignatureOnly, o.Force) - }, - } - - o.AddFlags(cmd) - return cmd -} diff --git a/cmd/cosign/cli/copy/copy.go b/cmd/cosign/cli/copy/copy.go deleted file mode 100644 index 59eea826d..000000000 --- a/cmd/cosign/cli/copy/copy.go +++ /dev/null @@ -1,156 +0,0 @@ -// Copyright 2021 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 copy - -import ( - "context" - "errors" - "fmt" - "net/http" - "os" - - "github.com/google/go-containerregistry/pkg/name" - v1 "github.com/google/go-containerregistry/pkg/v1" - "github.com/google/go-containerregistry/pkg/v1/remote" - "github.com/google/go-containerregistry/pkg/v1/remote/transport" - "github.com/sigstore/policy-controller/cmd/cosign/cli/options" - "github.com/sigstore/policy-controller/pkg/oci" - ociremote "github.com/sigstore/policy-controller/pkg/oci/remote" - "github.com/sigstore/policy-controller/pkg/oci/walk" -) - -// CopyCmd implements the logic to copy the supplied container image and signatures. -// nolint -func CopyCmd(ctx context.Context, regOpts options.RegistryOptions, srcImg, dstImg string, sigOnly, force bool) error { - srcRef, err := name.ParseReference(srcImg) - if err != nil { - return err - } - srcRepoRef := srcRef.Context() - - dstRef, err := name.ParseReference(dstImg) - if err != nil { - return err - } - dstRepoRef := dstRef.Context() - - remoteOpts := regOpts.GetRegistryClientOpts(ctx) - root, err := ociremote.SignedEntity(srcRef, ociremote.WithRemoteOptions(remoteOpts...)) - if err != nil { - return err - } - - if err := walk.SignedEntity(ctx, root, func(ctx context.Context, se oci.SignedEntity) error { - // Both of the SignedEntity types implement Digest() - h, err := se.(interface{ Digest() (v1.Hash, error) }).Digest() - if err != nil { - return err - } - srcDigest := srcRepoRef.Digest(h.String()) - - // Copy signatures. - if err := copyTagImage(ociremote.SignatureTag, srcDigest, dstRepoRef, force, remoteOpts...); err != nil { - return err - } - if sigOnly { - return nil - } - - // Copy attestations - if err := copyTagImage(ociremote.AttestationTag, srcDigest, dstRepoRef, force, remoteOpts...); err != nil { - return err - } - - // Copy SBOMs - if err := copyTagImage(ociremote.SBOMTag, srcDigest, dstRepoRef, force, remoteOpts...); err != nil { - return err - } - - // Copy the entity itself. - if err := copyImage(srcDigest, dstRepoRef.Tag(srcDigest.Identifier()), force, remoteOpts...); err != nil { - return err - } - - return nil - }); err != nil { - return err - } - if sigOnly { - return nil - } - - // Now that everything has been copied over, update the tag. - h, err := root.(interface{ Digest() (v1.Hash, error) }).Digest() - if err != nil { - return err - } - return copyImage(srcRepoRef.Digest(h.String()), dstRef, force, remoteOpts...) -} - -func descriptorsEqual(a, b *v1.Descriptor) bool { - if a == nil || b == nil { - return a == nil && b == nil - } - return a.Digest == b.Digest -} - -type tagMap func(name.Reference, ...ociremote.Option) (name.Tag, error) - -func copyTagImage(tm tagMap, srcDigest name.Digest, dstRepo name.Repository, overwrite bool, opts ...remote.Option) error { - src, err := tm(srcDigest, ociremote.WithRemoteOptions(opts...)) - if err != nil { - return err - } - return copyImage(src, dstRepo.Tag(src.Identifier()), overwrite, opts...) -} - -func copyImage(src, dest name.Reference, overwrite bool, opts ...remote.Option) error { - got, err := remote.Get(src, opts...) - if err != nil { - var te *transport.Error - if errors.As(err, &te) && te.StatusCode == http.StatusNotFound { - // We do not treat 404s on the source image as errors because we are - // trying many flavors of tag (sig, sbom, att) and only a subset of - // these are likely to exist, especially when we're talking about a - // multi-arch image. - return nil - } - return err - } - - if !overwrite { - if dstDesc, err := remote.Head(dest, opts...); err == nil { - if descriptorsEqual(&got.Descriptor, dstDesc) { - return nil - } - return fmt.Errorf("image %q already exists. Use `-f` to overwrite", dest.Name()) - } - } - - fmt.Fprintf(os.Stderr, "Copying %s to %s...\n", src, dest) - if got.MediaType.IsIndex() { - imgIdx, err := got.ImageIndex() - if err != nil { - return err - } - return remote.WriteIndex(dest, imgIdx, opts...) - } - - img, err := got.Image() - if err != nil { - return err - } - return remote.Write(dest, img, opts...) -} diff --git a/cmd/cosign/cli/dockerfile.go b/cmd/cosign/cli/dockerfile.go deleted file mode 100644 index ce801af48..000000000 --- a/cmd/cosign/cli/dockerfile.go +++ /dev/null @@ -1,112 +0,0 @@ -// -// Copyright 2021 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 cli - -import ( - "github.com/sigstore/policy-controller/cmd/cosign/cli/dockerfile" - "github.com/sigstore/policy-controller/cmd/cosign/cli/verify" - "github.com/spf13/cobra" - - "github.com/sigstore/policy-controller/cmd/cosign/cli/options" -) - -func Dockerfile() *cobra.Command { - cmd := &cobra.Command{ - Use: "dockerfile", - Short: "Provides utilities for discovering images in and performing operations on Dockerfiles", - } - - cmd.AddCommand( - dockerfileVerify(), - ) - - return cmd -} - -func dockerfileVerify() *cobra.Command { - o := &options.VerifyDockerfileOptions{} - - cmd := &cobra.Command{ - Use: "verify", - Short: "Verify a signature on the base image specified in the Dockerfile", - Long: `Verify signature and annotations on images in a Dockerfile by checking claims -against the transparency log. - -Shell-like variables in the Dockerfile's FROM lines will be substituted with values from the OS ENV.`, - Example: ` cosign dockerfile verify --key || - - # verify cosign claims and signing certificates on the FROM images in the Dockerfile - cosign dockerfile verify - - # only verify the base image (the last FROM image) - cosign dockerfile verify --base-image-only - - # additionally verify specified annotations - cosign dockerfile verify -a key1=val1 -a key2=val2 - - # (experimental) additionally, verify with the transparency log - COSIGN_EXPERIMENTAL=1 cosign dockerfile verify - - # verify images with public key - cosign dockerfile verify --key cosign.pub - - # verify images with public key provided by URL - cosign dockerfile verify --key https://host.for/ - - # verify images with public key stored in Azure Key Vault - cosign dockerfile verify --key azurekms://[VAULT_NAME][VAULT_URI]/[KEY] - - # verify images with public key stored in AWS KMS - cosign dockerfile verify --key awskms://[ENDPOINT]/[ID/ALIAS/ARN] - - # verify images with public key stored in Google Cloud KMS - cosign dockerfile verify --key gcpkms://projects/[PROJECT]/locations/global/keyRings/[KEYRING]/cryptoKeys/[KEY] - - # verify images with public key stored in Hashicorp Vault - cosign dockerfile verify --key hashivault://[KEY] `, - Args: cobra.ExactArgs(1), - RunE: func(cmd *cobra.Command, args []string) error { - annotations, err := o.AnnotationsMap() - if err != nil { - return err - } - v := &dockerfile.VerifyDockerfileCommand{ - VerifyCommand: verify.VerifyCommand{ - RegistryOptions: o.Registry, - CheckClaims: o.CheckClaims, - KeyRef: o.Key, - CertRef: o.CertVerify.Cert, - CertEmail: o.CertVerify.CertEmail, - CertOidcIssuer: o.CertVerify.CertOidcIssuer, - CertChain: o.CertVerify.CertChain, - EnforceSCT: o.CertVerify.EnforceSCT, - Sk: o.SecurityKey.Use, - Slot: o.SecurityKey.Slot, - Output: o.Output, - RekorURL: o.Rekor.URL, - Attachment: o.Attachment, - Annotations: annotations, - }, - BaseOnly: o.BaseImageOnly, - } - return v.Exec(cmd.Context(), args) - }, - } - - o.AddFlags(cmd) - - return cmd -} diff --git a/cmd/cosign/cli/dockerfile/verify.go b/cmd/cosign/cli/dockerfile/verify.go deleted file mode 100644 index 6656fe688..000000000 --- a/cmd/cosign/cli/dockerfile/verify.go +++ /dev/null @@ -1,96 +0,0 @@ -// Copyright 2021 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 dockerfile - -import ( - "bufio" - "context" - "errors" - "flag" - "fmt" - "io" - "os" - "strings" - - "github.com/sigstore/policy-controller/cmd/cosign/cli/verify" -) - -// VerifyCommand verifies a signature on a supplied container image -// nolint -type VerifyDockerfileCommand struct { - verify.VerifyCommand - BaseOnly bool -} - -// Exec runs the verification command -func (c *VerifyDockerfileCommand) Exec(ctx context.Context, args []string) error { - if len(args) != 1 { - return flag.ErrHelp - } - - dockerfile, err := os.Open(args[0]) - if err != nil { - return fmt.Errorf("could not open Dockerfile: %w", err) - } - defer dockerfile.Close() - - images, err := getImagesFromDockerfile(dockerfile) - if err != nil { - return fmt.Errorf("failed extracting images from Dockerfile: %w", err) - } - if len(images) == 0 { - return errors.New("no images found in Dockerfile") - } - if c.BaseOnly { - images = images[len(images)-1:] - } - fmt.Fprintf(os.Stderr, "Extracted image(s): %s\n", strings.Join(images, ", ")) - - return c.VerifyCommand.Exec(ctx, images) -} - -func getImagesFromDockerfile(dockerfile io.Reader) ([]string, error) { - var images []string - fileScanner := bufio.NewScanner(dockerfile) - for fileScanner.Scan() { - line := strings.TrimSpace(fileScanner.Text()) - if strings.HasPrefix(strings.ToUpper(line), "FROM") { - switch image := getImageFromLine(line); image { - case "scratch": - fmt.Fprintln(os.Stderr, "- scratch image ignored") - default: - images = append(images, image) - } - } - } - if err := fileScanner.Err(); err != nil { - return nil, err - } - return images, nil -} - -func getImageFromLine(line string) string { - line = strings.TrimPrefix(line, "FROM") // Remove "FROM" prefix - line = os.ExpandEnv(line) // Substitute templated vars - fields := strings.Fields(line) - for i := len(fields) - 1; i > 0; i-- { - // Remove the "AS" portion of line - if strings.EqualFold(fields[i], "AS") { - fields = fields[:i] - break - } - } - return fields[len(fields)-1] // The image should be the last portion of the line that remains -} diff --git a/cmd/cosign/cli/dockerfile/verify_test.go b/cmd/cosign/cli/dockerfile/verify_test.go deleted file mode 100644 index 86672c6f3..000000000 --- a/cmd/cosign/cli/dockerfile/verify_test.go +++ /dev/null @@ -1,105 +0,0 @@ -// Copyright 2021 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 dockerfile - -import ( - "os" - "reflect" - "strings" - "testing" -) - -func TestGetImagesFromDockerfile(t *testing.T) { - testCases := []struct { - name string - fileContents string - env map[string]string - expected []string - }{ - { - name: "plain", - fileContents: `FROM gcr.io/test/image`, - expected: []string{"gcr.io/test/image"}, - }, - { - name: "tag", - fileContents: `FROM gcr.io/test/image:latest`, - expected: []string{"gcr.io/test/image:latest"}, - }, - { - name: "tag with as", - fileContents: `FROM gcr.io/test/image:1.16.5 as build`, - expected: []string{"gcr.io/test/image:1.16.5"}, - }, - { - name: "digest", - fileContents: `FROM gcr.io/test/image@sha256:d131624e6f5d8695e9aea7a0439f7bac0fcc50051282e0c3d4d627cab8845ba5`, - expected: []string{"gcr.io/test/image@sha256:d131624e6f5d8695e9aea7a0439f7bac0fcc50051282e0c3d4d627cab8845ba5"}, - }, - { - name: "fancy-from", - fileContents: `FROM --platform=linux/arm64 gcr.io/fancy/test/image AS fancy`, - expected: []string{"gcr.io/fancy/test/image"}, - }, - { - name: "multistage", - fileContents: `FROM build_image_1 - RUN script1 - FROM build_image_2 - RUN script2 - FROM runtime_image - CMD bin`, - expected: []string{"build_image_1", "build_image_2", "runtime_image"}, - }, - { - name: "with-arg", - fileContents: `FROM gcr.io/${TEST_IMAGE_REPO_PATH}`, - env: map[string]string{ - "TEST_IMAGE_REPO_PATH": "env/var/test/repo", - }, - expected: []string{"gcr.io/env/var/test/repo"}, - }, - { - name: "gauntlet", - fileContents: `FROM gcr.io/${TEST_IMAGE_REPO_PATH}/one AS one - RUN script1 - FROM gcr.io/$TEST_IMAGE_REPO_PATH/${TEST_SUBREPO}:latest - RUN script2 - FROM --platform=linux/amd64 gcr.io/${TEST_IMAGE_REPO_PATH}/$TEST_RUNTIME_SUBREPO - CMD bin`, - env: map[string]string{ - "TEST_IMAGE_REPO_PATH": "gauntlet/test", - "TEST_SUBREPO": "two", - "TEST_RUNTIME_SUBREPO": "runtime", - "SOMETHING_ELSE": "something/else", - }, - expected: []string{"gcr.io/gauntlet/test/one", "gcr.io/gauntlet/test/two:latest", "gcr.io/gauntlet/test/runtime"}, - }, - } - for _, tc := range testCases { - t.Run(tc.name, func(t *testing.T) { - for k, v := range tc.env { - os.Setenv(k, v) - defer os.Unsetenv(k) - } - got, err := getImagesFromDockerfile(strings.NewReader(tc.fileContents)) - if err != nil { - t.Fatalf("getImagesFromDockerfile returned error: %v", err) - } - if !reflect.DeepEqual(tc.expected, got) { - t.Errorf("getImagesFromDockerfile returned %v, wanted %v", got, tc.expected) - } - }) - } -} diff --git a/cmd/cosign/cli/download.go b/cmd/cosign/cli/download.go deleted file mode 100644 index 9672f08fe..000000000 --- a/cmd/cosign/cli/download.go +++ /dev/null @@ -1,97 +0,0 @@ -// -// Copyright 2021 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 cli - -import ( - "fmt" - "os" - - "github.com/spf13/cobra" - - "github.com/sigstore/policy-controller/cmd/cosign/cli/download" - "github.com/sigstore/policy-controller/cmd/cosign/cli/options" -) - -func Download() *cobra.Command { - cmd := &cobra.Command{ - Use: "download", - Short: "Provides utilities for downloading artifacts and attached artifacts in a registry", - } - - cmd.AddCommand( - downloadSignature(), - downloadSBOM(), - downloadAttestation(), - ) - - return cmd -} - -func downloadSignature() *cobra.Command { - o := &options.RegistryOptions{} - - cmd := &cobra.Command{ - Use: "signature", - Short: "Download signatures from the supplied container image", - Example: " cosign download signature ", - Args: cobra.ExactArgs(1), - RunE: func(cmd *cobra.Command, args []string) error { - return download.SignatureCmd(cmd.Context(), *o, args[0]) - }, - } - - o.AddFlags(cmd) - - return cmd -} - -func downloadSBOM() *cobra.Command { - o := &options.RegistryOptions{} - - cmd := &cobra.Command{ - Use: "sbom", - Short: "Download SBOMs from the supplied container image", - Example: " cosign download sbom ", - Args: cobra.ExactArgs(1), - RunE: func(cmd *cobra.Command, args []string) error { - fmt.Fprintln(os.Stderr, "WARNING: Downloading SBOMs this way does not ensure its authenticity. If you want to ensure a tamper-proof SBOM, download it using 'cosign download attestation ' or verify its signature.") - _, err := download.SBOMCmd(cmd.Context(), *o, args[0], cmd.OutOrStdout()) - return err - }, - } - - o.AddFlags(cmd) - - return cmd -} - -func downloadAttestation() *cobra.Command { - o := &options.RegistryOptions{} - - cmd := &cobra.Command{ - Use: "attestation", - Short: "Download in-toto attestations from the supplied container image", - Example: " cosign download attestation ", - Args: cobra.ExactArgs(1), - RunE: func(cmd *cobra.Command, args []string) error { - return download.AttestationCmd(cmd.Context(), *o, args[0]) - }, - } - - o.AddFlags(cmd) - - return cmd -} diff --git a/cmd/cosign/cli/download/attestation.go b/cmd/cosign/cli/download/attestation.go deleted file mode 100644 index 443513f5b..000000000 --- a/cmd/cosign/cli/download/attestation.go +++ /dev/null @@ -1,49 +0,0 @@ -// -// Copyright 2021 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 download - -import ( - "context" - "encoding/json" - "fmt" - - "github.com/google/go-containerregistry/pkg/name" - "github.com/sigstore/policy-controller/cmd/cosign/cli/options" - "github.com/sigstore/policy-controller/pkg/cosign" -) - -func AttestationCmd(ctx context.Context, regOpts options.RegistryOptions, imageRef string) error { - ref, err := name.ParseReference(imageRef) - if err != nil { - return err - } - ociremoteOpts, err := regOpts.ClientOpts(ctx) - if err != nil { - return err - } - attestations, err := cosign.FetchAttestationsForReference(ctx, ref, ociremoteOpts...) - if err != nil { - return err - } - for _, att := range attestations { - b, err := json.Marshal(att) - if err != nil { - return err - } - fmt.Println(string(b)) - } - return nil -} diff --git a/cmd/cosign/cli/download/sbom.go b/cmd/cosign/cli/download/sbom.go deleted file mode 100644 index 79cd9ff8e..000000000 --- a/cmd/cosign/cli/download/sbom.go +++ /dev/null @@ -1,68 +0,0 @@ -// -// Copyright 2021 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 download - -import ( - "context" - "fmt" - "io" - "os" - - "github.com/google/go-containerregistry/pkg/name" - "github.com/sigstore/policy-controller/cmd/cosign/cli/options" - ociremote "github.com/sigstore/policy-controller/pkg/oci/remote" -) - -func SBOMCmd(ctx context.Context, regOpts options.RegistryOptions, imageRef string, out io.Writer) ([]string, error) { - ref, err := name.ParseReference(imageRef) - if err != nil { - return nil, err - } - - ociremoteOpts, err := regOpts.ClientOpts(ctx) - if err != nil { - return nil, err - } - - se, err := ociremote.SignedEntity(ref, ociremoteOpts...) - if err != nil { - return nil, err - } - - file, err := se.Attachment("sbom") - if err != nil { - return nil, err - } - - // "attach sbom" attaches a single static.NewFile - sboms := make([]string, 0, 1) - - mt, err := file.FileMediaType() - if err != nil { - return nil, err - } - - fmt.Fprintf(os.Stderr, "Found SBOM of media type: %s\n", mt) - sbom, err := file.Payload() - if err != nil { - return nil, err - } - - sboms = append(sboms, string(sbom)) - fmt.Fprint(out, string(sbom)) - - return sboms, nil -} diff --git a/cmd/cosign/cli/download/signature.go b/cmd/cosign/cli/download/signature.go deleted file mode 100644 index 44af591c7..000000000 --- a/cmd/cosign/cli/download/signature.go +++ /dev/null @@ -1,49 +0,0 @@ -// -// Copyright 2021 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 download - -import ( - "context" - "encoding/json" - "fmt" - - "github.com/google/go-containerregistry/pkg/name" - "github.com/sigstore/policy-controller/cmd/cosign/cli/options" - "github.com/sigstore/policy-controller/pkg/cosign" -) - -func SignatureCmd(ctx context.Context, regOpts options.RegistryOptions, imageRef string) error { - ref, err := name.ParseReference(imageRef) - if err != nil { - return err - } - ociremoteOpts, err := regOpts.ClientOpts(ctx) - if err != nil { - return err - } - signatures, err := cosign.FetchSignaturesForReference(ctx, ref, ociremoteOpts...) - if err != nil { - return err - } - for _, sig := range signatures { - b, err := json.Marshal(sig) - if err != nil { - return err - } - fmt.Println(string(b)) - } - return nil -} diff --git a/cmd/cosign/cli/generate.go b/cmd/cosign/cli/generate.go deleted file mode 100644 index 007bda215..000000000 --- a/cmd/cosign/cli/generate.go +++ /dev/null @@ -1,57 +0,0 @@ -// -// Copyright 2021 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 cli - -import ( - "github.com/spf13/cobra" - - "github.com/sigstore/policy-controller/cmd/cosign/cli/generate" - "github.com/sigstore/policy-controller/cmd/cosign/cli/options" -) - -func Generate() *cobra.Command { - o := &options.GenerateOptions{} - - cmd := &cobra.Command{ - Use: "generate", - Short: "Generates (unsigned) signature payloads from the supplied container image.", - Long: `Generates an unsigned payload from the supplied container image and flags. -This payload matches the one generated by the "cosign sign" command and can be used if you need -to sign payloads with your own tooling or algorithms.`, - Example: ` cosign generate [--a key=value] - - # Generate a simple payload for an image - cosign generate - - # Generate a payload with specific annotations - cosign generate -a foo=bar - - # Use this payload in another tool - gpg --output image.sig --detach-sig <(cosign generate )`, - - Args: cobra.ExactArgs(1), - RunE: func(cmd *cobra.Command, args []string) error { - annotationMap, err := o.AnnotationsMap() - if err != nil { - return err - } - return generate.GenerateCmd(cmd.Context(), o.Registry, args[0], annotationMap.Annotations, cmd.OutOrStdout()) - }, - } - - o.AddFlags(cmd) - return cmd -} diff --git a/cmd/cosign/cli/generate/generate.go b/cmd/cosign/cli/generate/generate.go deleted file mode 100644 index fe678ff16..000000000 --- a/cmd/cosign/cli/generate/generate.go +++ /dev/null @@ -1,54 +0,0 @@ -// -// Copyright 2021 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 generate - -import ( - "context" - "fmt" - "io" - - "github.com/google/go-containerregistry/pkg/name" - "github.com/sigstore/policy-controller/cmd/cosign/cli/options" - ociremote "github.com/sigstore/policy-controller/pkg/oci/remote" - "github.com/sigstore/sigstore/pkg/signature/payload" -) - -// nolint -func GenerateCmd(ctx context.Context, regOpts options.RegistryOptions, imageRef string, annotations map[string]interface{}, w io.Writer) error { - ref, err := name.ParseReference(imageRef) - if err != nil { - return err - } - ociremoteOpts, err := regOpts.ClientOpts(ctx) - if err != nil { - return err - } - digest, err := ociremote.ResolveDigest(ref, ociremoteOpts...) - if err != nil { - return err - } - // Overwrite "ref" with a digest to avoid a race where we use a tag - // multiple times, and it potentially points to different things at - // each access. - ref = digest - - json, err := (&payload.Cosign{Image: digest, Annotations: annotations}).MarshalJSON() - if err != nil { - return err - } - fmt.Fprintln(w, string(json)) - return nil -} diff --git a/cmd/cosign/cli/generate/generate_key_pair.go b/cmd/cosign/cli/generate/generate_key_pair.go deleted file mode 100644 index f0787ec1a..000000000 --- a/cmd/cosign/cli/generate/generate_key_pair.go +++ /dev/null @@ -1,136 +0,0 @@ -// -// Copyright 2021 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 generate - -import ( - "context" - "crypto" - "errors" - "fmt" - "io" - "os" - "strings" - - "github.com/sigstore/policy-controller/pkg/cosign/git" - "github.com/sigstore/policy-controller/pkg/cosign/git/github" - "github.com/sigstore/policy-controller/pkg/cosign/git/gitlab" - - "github.com/sigstore/policy-controller/pkg/cosign" - "github.com/sigstore/policy-controller/pkg/cosign/kubernetes" - "github.com/sigstore/sigstore/pkg/cryptoutils" - "github.com/sigstore/sigstore/pkg/signature/kms" -) - -var ( - // Read is for fuzzing - Read = readPasswordFn -) - -// nolint -func GenerateKeyPairCmd(ctx context.Context, kmsVal string, args []string) error { - if kmsVal != "" { - k, err := kms.Get(ctx, kmsVal, crypto.SHA256) - if err != nil { - return err - } - pubKey, err := k.CreateKey(ctx, k.DefaultAlgorithm()) - if err != nil { - return fmt.Errorf("creating key: %w", err) - } - pemBytes, err := cryptoutils.MarshalPublicKeyToPEM(pubKey) - if err != nil { - return err - } - if err := os.WriteFile("cosign.pub", pemBytes, 0600); err != nil { - return err - } - fmt.Fprintln(os.Stderr, "Public key written to cosign.pub") - return nil - } - - if len(args) > 0 { - split := strings.Split(args[0], "://") - - if len(split) < 2 { - return errors.New("could not parse scheme, use :// format") - } - - provider, targetRef := split[0], split[1] - - switch provider { - case "k8s": - return kubernetes.KeyPairSecret(ctx, targetRef, GetPass) - case gitlab.ReferenceScheme, github.ReferenceScheme: - return git.GetProvider(provider).PutSecret(ctx, targetRef, GetPass) - } - - return fmt.Errorf("undefined provider: %s", provider) - } - - keys, err := cosign.GenerateKeyPair(GetPass) - if err != nil { - return err - } - - if cosign.FileExists("cosign.key") { - var overwrite string - fmt.Fprint(os.Stderr, "File cosign.key already exists. Overwrite (y/n)? ") - fmt.Scanf("%s", &overwrite) - switch overwrite { - case "y", "Y": - case "n", "N": - return nil - default: - fmt.Fprintln(os.Stderr, "Invalid input") - return nil - } - } - // TODO: make sure the perms are locked down first. - if err := os.WriteFile("cosign.key", keys.PrivateBytes, 0600); err != nil { - return err - } - fmt.Fprintln(os.Stderr, "Private key written to cosign.key") - - if err := os.WriteFile("cosign.pub", keys.PublicBytes, 0644); err != nil { - return err - } // #nosec G306 - fmt.Fprintln(os.Stderr, "Public key written to cosign.pub") - return nil -} - -func GetPass(confirm bool) ([]byte, error) { - read := Read(confirm) - return read() -} - -func readPasswordFn(confirm bool) func() ([]byte, error) { - pw, ok := os.LookupEnv("COSIGN_PASSWORD") - switch { - case ok: - return func() ([]byte, error) { - return []byte(pw), nil - } - case cosign.IsTerminal(): - return func() ([]byte, error) { - return cosign.GetPassFromTerm(confirm) - } - // Handle piped in passwords. - default: - return func() ([]byte, error) { - return io.ReadAll(os.Stdin) - } - } -} diff --git a/cmd/cosign/cli/generate/generate_key_pair_test.go b/cmd/cosign/cli/generate/generate_key_pair_test.go deleted file mode 100644 index 07d73d3c1..000000000 --- a/cmd/cosign/cli/generate/generate_key_pair_test.go +++ /dev/null @@ -1,47 +0,0 @@ -// -// Copyright 2021 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 generate - -import ( - "os" - "testing" - - "github.com/google/go-cmp/cmp" -) - -func TestReadPasswordFn_env(t *testing.T) { - os.Setenv("COSIGN_PASSWORD", "foo") - defer os.Unsetenv("COSIGN_PASSWORD") - b, err := readPasswordFn(true)() - if err != nil { - t.Fatalf("unexpected error: %v", err) - } - if diff := cmp.Diff("foo", string(b)); diff != "" { - t.Fatal(diff) - } -} - -func TestReadPasswordFn_envEmptyVal(t *testing.T) { - os.Setenv("COSIGN_PASSWORD", "") - defer os.Unsetenv("COSIGN_PASSWORD") - b, err := readPasswordFn(true)() - if err != nil { - t.Fatalf("unexpected error: %v", err) - } - if len(b) > 0 { - t.Fatalf("expected empty string; got %q", string(b)) - } -} diff --git a/cmd/cosign/cli/generate_key_pair.go b/cmd/cosign/cli/generate_key_pair.go deleted file mode 100644 index 70b069e68..000000000 --- a/cmd/cosign/cli/generate_key_pair.go +++ /dev/null @@ -1,72 +0,0 @@ -// -// Copyright 2021 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 cli - -import ( - "github.com/spf13/cobra" - - "github.com/sigstore/policy-controller/cmd/cosign/cli/generate" - "github.com/sigstore/policy-controller/cmd/cosign/cli/options" -) - -func GenerateKeyPair() *cobra.Command { - o := &options.GenerateKeyPairOptions{} - - cmd := &cobra.Command{ - Use: "generate-key-pair", - Short: "Generates a key-pair.", - Long: "Generates a key-pair for signing.", - Example: ` cosign generate-key-pair [--kms KMSPATH] - - # generate key-pair and write to cosign.key and cosign.pub files - cosign generate-key-pair - - # generate a key-pair in Azure Key Vault - cosign generate-key-pair --kms azurekms://[VAULT_NAME][VAULT_URI]/[KEY] - - # generate a key-pair in AWS KMS - cosign generate-key-pair --kms awskms://[ENDPOINT]/[ID/ALIAS/ARN] - - # generate a key-pair in Google Cloud KMS - cosign generate-key-pair --kms gcpkms://projects/[PROJECT]/locations/global/keyRings/[KEYRING]/cryptoKeys/[KEY] - - # generate a key-pair in Hashicorp Vault - cosign generate-key-pair --kms hashivault://[KEY] - - # generate a key-pair in Kubernetes Secret - cosign generate-key-pair k8s://[NAMESPACE]/[NAME] - - # generate a key-pair in GitHub - cosign generate-key-pair github://[OWNER]/[PROJECT_NAME] - - # generate a key-pair in GitLab with project name - cosign generate-key-pair gitlab://[OWNER]/[PROJECT_NAME] - - # generate a key-pair in GitLab with project id - cosign generate-key-pair gitlab://[PROJECT_ID] - -CAVEATS: - This command interactively prompts for a password. You can use - the COSIGN_PASSWORD environment variable to provide one.`, - - RunE: func(cmd *cobra.Command, args []string) error { - return generate.GenerateKeyPairCmd(cmd.Context(), o.KMS, args) - }, - } - - o.AddFlags(cmd) - return cmd -} diff --git a/cmd/cosign/cli/import_key_pair.go b/cmd/cosign/cli/import_key_pair.go deleted file mode 100644 index 5fb324dd1..000000000 --- a/cmd/cosign/cli/import_key_pair.go +++ /dev/null @@ -1,48 +0,0 @@ -// -// Copyright 2021 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 cli - -import ( - "github.com/spf13/cobra" - - "github.com/sigstore/policy-controller/cmd/cosign/cli/importkeypair" - "github.com/sigstore/policy-controller/cmd/cosign/cli/options" -) - -func ImportKeyPair() *cobra.Command { - o := &options.ImportKeyPairOptions{} - - cmd := &cobra.Command{ - Use: "import-key-pair", - Short: "Imports a PEM-encoded RSA or EC private key.", - Long: "Imports a PEM-encoded RSA or EC private key for signing.", - Example: ` cosign import-key-pair --key openssl.key - - # import PEM-encoded RSA or EC private key and write to import-cosign.key and import-cosign.pub files - cosign import-key-pair --key - -CAVEATS: - This command interactively prompts for a password. You can use - the COSIGN_PASSWORD environment variable to provide one.`, - - RunE: func(cmd *cobra.Command, args []string) error { - return importkeypair.ImportKeyPairCmd(cmd.Context(), o.Key, args) - }, - } - - o.AddFlags(cmd) - return cmd -} diff --git a/cmd/cosign/cli/initialize.go b/cmd/cosign/cli/initialize.go deleted file mode 100644 index f8c19859d..000000000 --- a/cmd/cosign/cli/initialize.go +++ /dev/null @@ -1,61 +0,0 @@ -// -// Copyright 2021 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 cli - -import ( - "github.com/sigstore/policy-controller/cmd/cosign/cli/initialize" - "github.com/spf13/cobra" - - "github.com/sigstore/policy-controller/cmd/cosign/cli/options" -) - -func Initialize() *cobra.Command { - o := &options.InitializeOptions{} - - cmd := &cobra.Command{ - Use: "initialize", - Short: "Initializes SigStore root to retrieve trusted certificate and key targets for verification.", - Long: `Initializes SigStore root to retrieve trusted certificate and key targets for verification. - -The following options are used by default: - - The current trusted Sigstore TUF root is embedded inside cosign at the time of release. - - SigStore remote TUF repository is pulled from the GCS mirror at sigstore-tuf-root. - -To provide an out-of-band trusted initial root.json, use the -root flag with a file or URL reference. -This will enable you to point cosign to a separate TUF root. - -Any updated TUF repository will be written to $HOME/.sigstore/root/. - -Trusted keys and certificate used in cosign verification (e.g. verifying Fulcio issued certificates -with Fulcio root CA) are pulled form the trusted metadata.`, - Example: `cosign initialize -mirror -out - -# initialize root with distributed root keys, default mirror, and default out path. -cosign initialize - -# initialize with an out-of-band root key file, using the default mirror. -cosign initialize -root - -# initialize with an out-of-band root key file and custom repository mirror. -cosign initialize -mirror -root `, - RunE: func(cmd *cobra.Command, args []string) error { - return initialize.DoInitialize(cmd.Context(), o.Root, o.Mirror) - }, - } - - o.AddFlags(cmd) - return cmd -} diff --git a/cmd/cosign/cli/initialize/init.go b/cmd/cosign/cli/initialize/init.go deleted file mode 100644 index 5d838ffe8..000000000 --- a/cmd/cosign/cli/initialize/init.go +++ /dev/null @@ -1,54 +0,0 @@ -// -// Copyright 2021 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 initialize - -import ( - "context" - _ "embed" // To enable the `go:embed` directive. - "encoding/json" - "fmt" - - "github.com/sigstore/policy-controller/pkg/blob" - "github.com/sigstore/policy-controller/pkg/cosign/tuf" -) - -func DoInitialize(ctx context.Context, root, mirror string) error { - // Get the initial trusted root contents. - var rootFileBytes []byte - var err error - if root != "" { - rootFileBytes, err = blob.LoadFileOrURL(root) - if err != nil { - return err - } - } - - if err := tuf.Initialize(ctx, mirror, rootFileBytes); err != nil { - return err - } - - status, err := tuf.GetRootStatus(ctx) - if err != nil { - return err - } - b, err := json.MarshalIndent(status, "", "\t") - if err != nil { - return err - } - - fmt.Println("Root status: \n", string(b)) - return nil -} diff --git a/cmd/cosign/cli/load.go b/cmd/cosign/cli/load.go deleted file mode 100644 index 3293b19d0..000000000 --- a/cmd/cosign/cli/load.go +++ /dev/null @@ -1,59 +0,0 @@ -// -// Copyright 2021 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 cli - -import ( - "context" - "fmt" - - "github.com/google/go-containerregistry/pkg/name" - "github.com/sigstore/policy-controller/cmd/cosign/cli/options" - "github.com/sigstore/policy-controller/pkg/oci/layout" - "github.com/sigstore/policy-controller/pkg/oci/remote" - "github.com/spf13/cobra" -) - -func Load() *cobra.Command { - o := &options.LoadOptions{} - - cmd := &cobra.Command{ - Use: "load", - Short: "Load a signed image on disk to a remote registry", - Long: "Load a signed image on disk to a remote registry", - Example: ` cosign load --dir `, - Args: cobra.ExactArgs(1), - RunE: func(cmd *cobra.Command, args []string) error { - return LoadCmd(cmd.Context(), *o, args[0]) - }, - } - - o.AddFlags(cmd) - return cmd -} - -func LoadCmd(ctx context.Context, opts options.LoadOptions, imageRef string) error { - ref, err := name.ParseReference(imageRef) - if err != nil { - return fmt.Errorf("parsing image name %s: %w", imageRef, err) - } - - // get the signed image from disk - sii, err := layout.SignedImageIndex(opts.Directory) - if err != nil { - return fmt.Errorf("signed image index: %w", err) - } - return remote.WriteSignedImageIndexImages(ref, sii) -} diff --git a/cmd/cosign/cli/manifest.go b/cmd/cosign/cli/manifest.go deleted file mode 100644 index 4dd16b6fe..000000000 --- a/cmd/cosign/cli/manifest.go +++ /dev/null @@ -1,106 +0,0 @@ -// -// Copyright 2021 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 cli - -import ( - "github.com/sigstore/policy-controller/cmd/cosign/cli/manifest" - "github.com/sigstore/policy-controller/cmd/cosign/cli/verify" - "github.com/spf13/cobra" - - "github.com/sigstore/policy-controller/cmd/cosign/cli/options" -) - -func Manifest() *cobra.Command { - cmd := &cobra.Command{ - Use: "manifest", - Short: "Provides utilities for discovering images in and performing operations on Kubernetes manifests", - } - - cmd.AddCommand( - manifestVerify(), - ) - - return cmd -} - -func manifestVerify() *cobra.Command { - o := &options.VerifyOptions{} - - cmd := &cobra.Command{ - Use: "verify", - Short: "Verify all signatures of images specified in the manifest", - Long: `Verify all signature of images in a Kubernetes resource manifest by checking claims -against the transparency log.`, - Example: ` cosign manifest verify --key || - - # verify cosign claims and signing certificates on images in the manifest - cosign manifest verify - - # additionally verify specified annotations - cosign manifest verify -a key1=val1 -a key2=val2 - - # (experimental) additionally, verify with the transparency log - COSIGN_EXPERIMENTAL=1 cosign manifest verify - - # verify images with public key - cosign manifest verify --key cosign.pub - - # verify images with public key provided by URL - cosign manifest verify --key https://host.for/ - - # verify images with public key stored in Azure Key Vault - cosign manifest verify --key azurekms://[VAULT_NAME][VAULT_URI]/[KEY] - - # verify images with public key stored in AWS KMS - cosign manifest verify --key awskms://[ENDPOINT]/[ID/ALIAS/ARN] - - # verify images with public key stored in Google Cloud KMS - cosign manifest verify --key gcpkms://projects/[PROJECT]/locations/global/keyRings/[KEYRING]/cryptoKeys/[KEY] - - # verify images with public key stored in Hashicorp Vault - cosign manifest verify --key hashivault://[KEY] `, - Args: cobra.ExactArgs(1), - RunE: func(cmd *cobra.Command, args []string) error { - annotations, err := o.AnnotationsMap() - if err != nil { - return err - } - v := &manifest.VerifyManifestCommand{ - VerifyCommand: verify.VerifyCommand{ - RegistryOptions: o.Registry, - CheckClaims: o.CheckClaims, - KeyRef: o.Key, - CertRef: o.CertVerify.Cert, - CertEmail: o.CertVerify.CertEmail, - CertOidcIssuer: o.CertVerify.CertOidcIssuer, - CertChain: o.CertVerify.CertChain, - EnforceSCT: o.CertVerify.EnforceSCT, - Sk: o.SecurityKey.Use, - Slot: o.SecurityKey.Slot, - Output: o.Output, - RekorURL: o.Rekor.URL, - Attachment: o.Attachment, - Annotations: annotations, - }, - } - return v.Exec(cmd.Context(), args) - }, - } - - o.AddFlags(cmd) - - return cmd -} diff --git a/cmd/cosign/cli/manifest/verify.go b/cmd/cosign/cli/manifest/verify.go deleted file mode 100644 index 6a6171400..000000000 --- a/cmd/cosign/cli/manifest/verify.go +++ /dev/null @@ -1,159 +0,0 @@ -// Copyright 2021 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 manifest - -import ( - "bytes" - "context" - "errors" - "flag" - "fmt" - "io" - "os" - "path/filepath" - "strings" - - "k8s.io/apimachinery/pkg/util/yaml" - - "github.com/sigstore/policy-controller/cmd/cosign/cli/verify" -) - -// VerifyManifestCommand verifies all image signatures on a supplied k8s resource -type VerifyManifestCommand struct { - verify.VerifyCommand -} - -// Exec runs the verification command -func (c *VerifyManifestCommand) Exec(ctx context.Context, args []string) error { - if len(args) != 1 { - return flag.ErrHelp - } - - manifestPath := args[0] - - err := isExtensionAllowed(manifestPath) - if err != nil { - return fmt.Errorf("check if extension is valid: %w", err) - } - manifest, err := os.ReadFile(manifestPath) - if err != nil { - return fmt.Errorf("could not read manifest: %w", err) - } - - images, err := getImagesFromYamlManifest(manifest) - if err != nil { - return fmt.Errorf("unable to extract the container image references in the manifest %w", err) - } - if len(images) == 0 { - return errors.New("no images found in manifest") - } - fmt.Fprintf(os.Stderr, "Extracted image(s): %s\n", strings.Join(images, ", ")) - - return c.VerifyCommand.Exec(ctx, images) -} - -// unionImagesKind is the union type that match PodSpec, PodSpecTemplate, and -// JobSpecTemplate; but filtering all keys except for `Image`. -type unionImagesKind struct { - Spec struct { - // PodSpec - imageContainers `json:",inline"` - // PodSpecTemplate - Template struct { - Spec struct { - imageContainers `json:",inline"` - } - } - // JobSpecTemplate - JobTemplate struct { - Spec struct { - Template struct { - Spec struct { - imageContainers `json:",inline"` - } - } - } - } - } -} - -// imageContainers is a wrapper for `containers[].image` and `initContainers[].image` -type imageContainers struct { - Containers []struct { - Image string - } - InitContainers []struct { - Image string - } -} - -func (uik *unionImagesKind) images() []string { - images := []string(nil) - var addImage = func(ic *imageContainers) { - for _, c := range ic.InitContainers { - if len(c.Image) > 0 { - images = append(images, c.Image) - } - } - for _, c := range ic.Containers { - if len(c.Image) > 0 { - images = append(images, c.Image) - } - } - } - - // Pod - addImage(&uik.Spec.imageContainers) - - // Deployment, ReplicaSet, StatefulSet, DaemonSet, Job - addImage(&uik.Spec.Template.Spec.imageContainers) - - // CronJob - addImage(&uik.Spec.JobTemplate.Spec.Template.Spec.imageContainers) - - return images -} - -func getImagesFromYamlManifest(manifest []byte) ([]string, error) { - dec := yaml.NewYAMLOrJSONDecoder(bytes.NewReader(manifest), 4096) - var images []string - - for { - ic := unionImagesKind{} - if err := dec.Decode(&ic); err != nil { - if errors.Is(err, io.EOF) { - break - } - return images, errors.New("unable to decode the manifest") - } - images = append(images, ic.images()...) - } - - return images, nil -} - -func isExtensionAllowed(ext string) error { - allowedExtensions := allowedExtensionsForManifest() - for _, v := range allowedExtensions { - if strings.EqualFold(filepath.Ext(strings.TrimSpace(ext)), v) { - return nil - } - } - return fmt.Errorf("only %v manifests are supported at this time", allowedExtensions) -} - -func allowedExtensionsForManifest() []string { - return []string{".yaml", ".yml"} -} diff --git a/cmd/cosign/cli/manifest/verify_test.go b/cmd/cosign/cli/manifest/verify_test.go deleted file mode 100644 index 56f525f9d..000000000 --- a/cmd/cosign/cli/manifest/verify_test.go +++ /dev/null @@ -1,284 +0,0 @@ -// Copyright 2021 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 manifest - -import ( - "reflect" - "testing" -) - -const singleContainerManifest = ` -apiVersion: v1 -kind: Pod -metadata: - name: single-pod -spec: - restartPolicy: Never - containers: - - name: nginx-container - image: nginx:1.21.1 -` - -const initContainerManifest = ` -apiVersion: v1 -kind: Pod -metadata: - name: single-pod -spec: - restartPolicy: Never - initContainers: - - name: preflight - image: preflight:3.2.1 - containers: - - name: nginx-container - image: nginx:1.21.1 -` - -const multiContainerManifest = ` -apiVersion: v1 -kind: Pod -metadata: - name: multi-pod -spec: - restartPolicy: Never - volumes: - - name: shared-data - emptyDir: {} - containers: - - name: nginx-container - image: nginx:1.21.1 - volumeMounts: - - name: shared-data - mountPath: /usr/share/nginx/html - - name: ubuntu-container - image: ubuntu:21.10 - volumeMounts: - - name: shared-data - mountPath: /pod-data - command: ["/bin/sh"] - args: ["-c", "echo Hello, World > /pod-data/index.html"] -` - -const multiResourceContainerManifest = ` -apiVersion: apps/v1 -kind: Deployment -metadata: - name: nginx-deployment - labels: - app: nginx -spec: - replicas: 3 - selector: - matchLabels: - app: nginx - template: - metadata: - labels: - app: nginx - spec: - containers: - - name: nginx - image: nginx:1.14.2 - ports: - - containerPort: 80 ---- -apiVersion: v1 -kind: Pod -metadata: - name: multi-pod -spec: - restartPolicy: Never - volumes: - - name: shared-data - emptyDir: {} - containers: - - name: nginx-container - image: nginx:1.21.1 - volumeMounts: - - name: shared-data - mountPath: /usr/share/nginx/html - - name: ubuntu-container - image: ubuntu:21.10 - volumeMounts: - - name: shared-data - mountPath: /pod-data - command: ["/bin/sh"] - args: ["-c", "echo Hello, World > /pod-data/index.html"] -` - -const customContainerManifest = ` -apiVersion: v42 -kind: PodSpec -metadata: - name: custom-pod -spec: - restartPolicy: Never - containers: - - name: nginx-container - image: nginx:1.21.1 -` - -const daemonsetManifest = ` -apiVersion: apps/v1 -kind: DaemonSet -metadata: - name: fluentd-elasticsearch - namespace: kube-system - labels: - k8s-app: fluentd-logging -spec: - selector: - matchLabels: - name: fluentd-elasticsearch - template: - metadata: - labels: - name: fluentd-elasticsearch - spec: - tolerations: - # this toleration is to have the daemonset runnable on master nodes - # remove it if your masters can't run pods - - key: node-role.kubernetes.io/master - operator: Exists - effect: NoSchedule - initContainers: - - name: py - image: python - command: ["python", "-c", "import math;print(math.sin(1))"] - containers: - - name: fluentd-elasticsearch - image: quay.io/fluentd_elasticsearch/fluentd:v2.5.2 - resources: - limits: - memory: 200Mi - requests: - cpu: 100m - memory: 200Mi - volumeMounts: - - name: varlog - mountPath: /var/log - - name: varlibdockercontainers - mountPath: /var/lib/docker/containers - readOnly: true - terminationGracePeriodSeconds: 30 - volumes: - - name: varlog - hostPath: - path: /var/log - - name: varlibdockercontainers - hostPath: - path: /var/lib/docker/containers -` - -const jobManifest = ` -apiVersion: batch/v1 -kind: Job -metadata: - name: pi -spec: - template: - spec: - initContainers: - - name: py - image: python - command: ["python", "-c", "import math;print(math.sin(1))"] - containers: - - name: pi - image: perl - command: ["perl", "-Mbignum=bpi", "-wle", "print bpi(2000)"] - restartPolicy: Never - backoffLimit: 4 -` - -const cronJobManifest = ` -apiVersion: batch/v1 -kind: CronJob -metadata: - name: hello -spec: - schedule: "*/1 * * * *" - jobTemplate: - spec: - template: - spec: - initContainers: - - name: py - image: python - command: ["python", "-c", "booting up"] - containers: - - name: hello - image: busybox - imagePullPolicy: IfNotPresent - command: - - /bin/sh - - -c - - date; echo Hello from the Kubernetes cluster - restartPolicy: OnFailure -` - -func TestGetImagesFromYamlManifest(t *testing.T) { - testCases := []struct { - name string - fileContents []byte - expected []string - }{{ - name: "single image", - fileContents: []byte(singleContainerManifest), - expected: []string{"nginx:1.21.1"}, - }, { - name: "initialize and container images", - fileContents: []byte(initContainerManifest), - expected: []string{"preflight:3.2.1", "nginx:1.21.1"}, - }, { - name: "daemonsets", - fileContents: []byte(daemonsetManifest), - expected: []string{"python", "quay.io/fluentd_elasticsearch/fluentd:v2.5.2"}, - }, { - name: "jobs", - fileContents: []byte(jobManifest), - expected: []string{"python", "perl"}, - }, { - name: "cronjobs", - fileContents: []byte(cronJobManifest), - expected: []string{"python", "busybox"}, - }, { - name: "multi image", - fileContents: []byte(multiContainerManifest), - expected: []string{"nginx:1.21.1", "ubuntu:21.10"}, - }, { - name: "multiple resources and images within a document", - fileContents: []byte(multiResourceContainerManifest), - expected: []string{"nginx:1.14.2", "nginx:1.21.1", "ubuntu:21.10"}, - }, { - name: "no images found", - fileContents: []byte(``), - expected: nil, - }, { - name: "custom type single image", - fileContents: []byte(customContainerManifest), - expected: []string{"nginx:1.21.1"}, - }} - for _, tc := range testCases { - t.Run(tc.name, func(t *testing.T) { - got, err := getImagesFromYamlManifest(tc.fileContents) - if err != nil { - t.Fatalf("getImagesFromYamlManifest returned error: %v", err) - } - if !reflect.DeepEqual(tc.expected, got) { - t.Errorf("getImagesFromYamlManifest returned %v, wanted %v", got, tc.expected) - } - }) - } -} diff --git a/cmd/cosign/cli/options/attach.go b/cmd/cosign/cli/options/attach.go deleted file mode 100644 index 1ad32c648..000000000 --- a/cmd/cosign/cli/options/attach.go +++ /dev/null @@ -1,117 +0,0 @@ -// -// Copyright 2021 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 options - -import ( - "fmt" - "strings" - - "github.com/google/go-containerregistry/pkg/v1/types" - "github.com/spf13/cobra" - - ctypes "github.com/sigstore/policy-controller/pkg/types" -) - -// AttachSignatureOptions is the top level wrapper for the attach signature command. -type AttachSignatureOptions struct { - Signature string - Payload string - Registry RegistryOptions -} - -var _ Interface = (*AttachSignatureOptions)(nil) - -// AddFlags implements Interface -func (o *AttachSignatureOptions) AddFlags(cmd *cobra.Command) { - o.Registry.AddFlags(cmd) - - cmd.Flags().StringVar(&o.Signature, "signature", "", - "the signature, path to the signature, or {-} for stdin") - - cmd.Flags().StringVar(&o.Payload, "payload", "", - "path to the payload covered by the signature (if using another format)") -} - -// AttachSBOMOptions is the top level wrapper for the attach sbom command. -type AttachSBOMOptions struct { - SBOM string - SBOMType string - SBOMInputFormat string - Registry RegistryOptions -} - -var _ Interface = (*AttachSBOMOptions)(nil) - -// AddFlags implements Interface -func (o *AttachSBOMOptions) AddFlags(cmd *cobra.Command) { - o.Registry.AddFlags(cmd) - - cmd.Flags().StringVar(&o.SBOM, "sbom", "", - "path to the sbom, or {-} for stdin") - - cmd.Flags().StringVar(&o.SBOMType, "type", "spdx", - "type of sbom (spdx|cyclonedx|syft)") - - cmd.Flags().StringVar(&o.SBOMInputFormat, "input-format", "", - "type of sbom input format (json|xml|text)") -} - -func (o *AttachSBOMOptions) MediaType() (types.MediaType, error) { - var looksLikeJSON bool - if strings.HasSuffix(o.SBOM, ".json") { - looksLikeJSON = true - } - switch o.SBOMType { - case "cyclonedx": - if o.SBOMInputFormat != "" && o.SBOMInputFormat != ctypes.XMLInputFormat && o.SBOMInputFormat != ctypes.JSONInputFormat { - return "invalid", fmt.Errorf("invalid SBOM input format: %q, expected (json|xml)", o.SBOMInputFormat) - } - if o.SBOMInputFormat == ctypes.JSONInputFormat || looksLikeJSON { - return ctypes.CycloneDXJSONMediaType, nil - } - return ctypes.CycloneDXXMLMediaType, nil - - case "spdx": - if o.SBOMInputFormat != "" && o.SBOMInputFormat != ctypes.TextInputFormat && o.SBOMInputFormat != ctypes.JSONInputFormat { - return "invalid", fmt.Errorf("invalid SBOM input format: %q, expected (json|text)", o.SBOMInputFormat) - } - if o.SBOMInputFormat == ctypes.JSONInputFormat || looksLikeJSON { - return ctypes.SPDXJSONMediaType, nil - } - return ctypes.SPDXMediaType, nil - case "syft": - if o.SBOMInputFormat != "" && o.SBOMInputFormat != ctypes.JSONInputFormat { - return "invalid", fmt.Errorf("invalid SBOM input format: %q, expected (json)", o.SBOMInputFormat) - } - return ctypes.SyftMediaType, nil - default: - return "unknown", fmt.Errorf("unknown SBOM type: %q, expected (spdx|cyclonedx|syft)", o.SBOMType) - } -} - -// AttachAttestationOptions is the top level wrapper for the attach attestation command. -type AttachAttestationOptions struct { - Attestation string - Registry RegistryOptions -} - -// AddFlags implements Interface -func (o *AttachAttestationOptions) AddFlags(cmd *cobra.Command) { - o.Registry.AddFlags(cmd) - - cmd.Flags().StringVar(&o.Attestation, "attestation", "", - "path to the attestation envelope") -} diff --git a/cmd/cosign/cli/options/attest.go b/cmd/cosign/cli/options/attest.go deleted file mode 100644 index fee88d048..000000000 --- a/cmd/cosign/cli/options/attest.go +++ /dev/null @@ -1,74 +0,0 @@ -// -// Copyright 2021 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 options - -import ( - "github.com/spf13/cobra" -) - -// AttestOptions is the top level wrapper for the attest command. -type AttestOptions struct { - Key string - Cert string - CertChain string - NoUpload bool - Force bool - Recursive bool - Replace bool - - Rekor RekorOptions - Fulcio FulcioOptions - OIDC OIDCOptions - SecurityKey SecurityKeyOptions - Predicate PredicateLocalOptions - Registry RegistryOptions -} - -var _ Interface = (*AttestOptions)(nil) - -// AddFlags implements Interface -func (o *AttestOptions) AddFlags(cmd *cobra.Command) { - o.SecurityKey.AddFlags(cmd) - o.Predicate.AddFlags(cmd) - o.Fulcio.AddFlags(cmd) - o.OIDC.AddFlags(cmd) - o.Rekor.AddFlags(cmd) - o.Registry.AddFlags(cmd) - - cmd.Flags().StringVar(&o.Key, "key", "", - "path to the private key file, KMS URI or Kubernetes Secret") - - cmd.Flags().StringVar(&o.Cert, "certificate", "", - "path to the X.509 certificate in PEM format to include in the OCI Signature") - - cmd.Flags().StringVar(&o.CertChain, "certificate-chain", "", - "path to a list of CA X.509 certificates in PEM format which will be needed "+ - "when building the certificate chain for the signing certificate. "+ - "Must start with the parent intermediate CA certificate of the "+ - "signing certificate and end with the root certificate. Included in the OCI Signature") - - cmd.Flags().BoolVar(&o.NoUpload, "no-upload", false, - "do not upload the generated attestation") - - cmd.Flags().BoolVarP(&o.Force, "force", "f", false, - "skip warnings and confirmations") - - cmd.Flags().BoolVarP(&o.Recursive, "recursive", "r", false, - "if a multi-arch image is specified, additionally sign each discrete image") - - cmd.Flags().BoolVarP(&o.Replace, "replace", "", false, - "") -} diff --git a/cmd/cosign/cli/options/clean.go b/cmd/cosign/cli/options/clean.go deleted file mode 100644 index 32b4907b4..000000000 --- a/cmd/cosign/cli/options/clean.go +++ /dev/null @@ -1,31 +0,0 @@ -// Copyright 2022 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 options - -import "github.com/spf13/cobra" - -type CleanOptions struct { - Registry RegistryOptions - CleanType string - Force bool -} - -var _ Interface = (*CleanOptions)(nil) - -func (c *CleanOptions) AddFlags(cmd *cobra.Command) { - c.Registry.AddFlags(cmd) - cmd.Flags().StringVarP(&c.CleanType, "type", "", "all", "a type of clean: (default: all)") - cmd.Flags().BoolVarP(&c.Force, "force", "f", false, "do not prompt for confirmation") -} diff --git a/cmd/cosign/cli/options/copy.go b/cmd/cosign/cli/options/copy.go deleted file mode 100644 index e9c5c7013..000000000 --- a/cmd/cosign/cli/options/copy.go +++ /dev/null @@ -1,40 +0,0 @@ -// -// Copyright 2021 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 options - -import ( - "github.com/spf13/cobra" -) - -// CopyOptions is the top level wrapper for the copy command. -type CopyOptions struct { - SignatureOnly bool - Force bool - Registry RegistryOptions -} - -var _ Interface = (*CopyOptions)(nil) - -// AddFlags implements Interface -func (o *CopyOptions) AddFlags(cmd *cobra.Command) { - o.Registry.AddFlags(cmd) - - cmd.Flags().BoolVar(&o.SignatureOnly, "sig-only", false, - "only copy the image signature") - - cmd.Flags().BoolVarP(&o.Force, "force", "f", false, - "overwrite destination image(s), if necessary") -} diff --git a/cmd/cosign/cli/options/flags.go b/cmd/cosign/cli/options/flags.go deleted file mode 100644 index e9e57e8a7..000000000 --- a/cmd/cosign/cli/options/flags.go +++ /dev/null @@ -1,36 +0,0 @@ -// -// Copyright 2021 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 options - -import ( - "reflect" -) - -// OneOf ensures that only one of the supplied interfaces is set to a non-zero value. -func OneOf(args ...interface{}) bool { - return NOf(args...) == 1 -} - -// NOf returns how many of the fields are non-zero -func NOf(args ...interface{}) int { - n := 0 - for _, arg := range args { - if !reflect.ValueOf(arg).IsZero() { - n++ - } - } - return n -} diff --git a/cmd/cosign/cli/options/flags_test.go b/cmd/cosign/cli/options/flags_test.go deleted file mode 100644 index bf865d5f3..000000000 --- a/cmd/cosign/cli/options/flags_test.go +++ /dev/null @@ -1,84 +0,0 @@ -// -// Copyright 2021 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 options - -import "testing" - -func TestOneOf(t *testing.T) { - type dumbStruct struct { - A int - B []string - C bool - } - tests := []struct { - name string - args []interface{} - want bool - }{ - { - name: "3/3", - args: []interface{}{"one", 2, true}, - want: false, - }, - { - name: "2/3", - args: []interface{}{"one", 2, false}, - want: false, - }, - { - name: "1/3", - args: []interface{}{"", 2, false}, - want: true, - }, - { - name: "0/1", - args: []interface{}{""}, - want: false, - }, - { - name: "1/1", - args: []interface{}{"hey"}, - want: true, - }, - { - name: "structs", - args: []interface{}{"hey", dumbStruct{A: 2}}, - want: false, - }, - { - name: "struct", - args: []interface{}{"", dumbStruct{A: 2}}, - want: true, - }, - { - name: "pointers", - args: []interface{}{"hey", &struct{ a int }{a: 2}, false}, - want: false, - }, - { - name: "pointer", - args: []interface{}{&struct{ a int }{a: 2}, false}, - want: true, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - if got := OneOf(tt.args...); got != tt.want { - t.Errorf("OneOf() = %v, want %v", got, tt.want) - } - }) - } -} diff --git a/cmd/cosign/cli/options/generate.go b/cmd/cosign/cli/options/generate.go deleted file mode 100644 index 860ce753e..000000000 --- a/cmd/cosign/cli/options/generate.go +++ /dev/null @@ -1,34 +0,0 @@ -// -// Copyright 2021 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 options - -import ( - "github.com/spf13/cobra" -) - -// GenerateOptions is the top level wrapper for the generate command. -type GenerateOptions struct { - AnnotationOptions - Registry RegistryOptions -} - -var _ Interface = (*GenerateOptions)(nil) - -// AddFlags implements Interface -func (o *GenerateOptions) AddFlags(cmd *cobra.Command) { - o.AnnotationOptions.AddFlags(cmd) - o.Registry.AddFlags(cmd) -} diff --git a/cmd/cosign/cli/options/generate_key_pair.go b/cmd/cosign/cli/options/generate_key_pair.go deleted file mode 100644 index 4b7312d77..000000000 --- a/cmd/cosign/cli/options/generate_key_pair.go +++ /dev/null @@ -1,34 +0,0 @@ -// -// Copyright 2021 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 options - -import ( - "github.com/spf13/cobra" -) - -// GenerateKeyPairOptions is the top level wrapper for the generate-key-pair command. -type GenerateKeyPairOptions struct { - // KMS Key Management Service - KMS string -} - -var _ Interface = (*GenerateKeyPairOptions)(nil) - -// AddFlags implements Interface -func (o *GenerateKeyPairOptions) AddFlags(cmd *cobra.Command) { - cmd.Flags().StringVar(&o.KMS, "kms", "", - "create key pair in KMS service to use for signing") -} diff --git a/cmd/cosign/cli/options/import_key_pair.go b/cmd/cosign/cli/options/import_key_pair.go deleted file mode 100644 index b4d3ac3d4..000000000 --- a/cmd/cosign/cli/options/import_key_pair.go +++ /dev/null @@ -1,34 +0,0 @@ -// -// Copyright 2021 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 options - -import ( - "github.com/spf13/cobra" -) - -// ImportKeyPairOptions is the top level wrapper for the import-key-pair command. -type ImportKeyPairOptions struct { - // Local key file generated by external program such as OpenSSL - Key string -} - -var _ Interface = (*ImportKeyPairOptions)(nil) - -// AddFlags implements Interface -func (o *ImportKeyPairOptions) AddFlags(cmd *cobra.Command) { - cmd.Flags().StringVar(&o.Key, "key", "", - "import key pair to use for signing") -} diff --git a/cmd/cosign/cli/options/load.go b/cmd/cosign/cli/options/load.go deleted file mode 100644 index 4a6e9e9db..000000000 --- a/cmd/cosign/cli/options/load.go +++ /dev/null @@ -1,34 +0,0 @@ -// -// Copyright 2021 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 options - -import ( - "github.com/spf13/cobra" -) - -// LoadOptions is the top level wrapper for the load command. -type LoadOptions struct { - Directory string -} - -var _ Interface = (*LoadOptions)(nil) - -// AddFlags implements Interface -func (o *LoadOptions) AddFlags(cmd *cobra.Command) { - cmd.Flags().StringVar(&o.Directory, "dir", "", - "path to directory where the signed image is stored on disk") - _ = cmd.MarkFlagRequired("dir") -} diff --git a/cmd/cosign/cli/options/oidc.go b/cmd/cosign/cli/options/oidc.go deleted file mode 100644 index b5c87fb21..000000000 --- a/cmd/cosign/cli/options/oidc.go +++ /dev/null @@ -1,72 +0,0 @@ -// -// Copyright 2021 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 options - -import ( - "fmt" - "os" - "strings" - "unicode/utf8" - - "github.com/spf13/cobra" -) - -const DefaultOIDCIssuerURL = "https://oauth2.sigstore.dev/auth" - -// OIDCOptions is the wrapper for OIDC related options. -type OIDCOptions struct { - Issuer string - ClientID string - clientSecretFile string - RedirectURL string - DisableAmbientProviders bool -} - -func (o *OIDCOptions) ClientSecret() (string, error) { - if o.clientSecretFile != "" { - clientSecretBytes, err := os.ReadFile(o.clientSecretFile) - if err != nil { - return "", fmt.Errorf("reading OIDC client secret: %w", err) - } - if !utf8.Valid(clientSecretBytes) { - return "", fmt.Errorf("OIDC client secret in file %s not valid utf8", o.clientSecretFile) - } - clientSecretString := string(clientSecretBytes) - clientSecretString = strings.TrimSpace(clientSecretString) - return clientSecretString, nil - } - return "", nil -} - -var _ Interface = (*OIDCOptions)(nil) - -// AddFlags implements Interface -func (o *OIDCOptions) AddFlags(cmd *cobra.Command) { - cmd.Flags().StringVar(&o.Issuer, "oidc-issuer", DefaultOIDCIssuerURL, - "[EXPERIMENTAL] OIDC provider to be used to issue ID token") - - cmd.Flags().StringVar(&o.ClientID, "oidc-client-id", "sigstore", - "[EXPERIMENTAL] OIDC client ID for application") - - cmd.Flags().StringVar(&o.clientSecretFile, "oidc-client-secret-file", "", - "[EXPERIMENTAL] Path to file containing OIDC client secret for application") - - cmd.Flags().StringVar(&o.RedirectURL, "oidc-redirect-url", "", - "[EXPERIMENTAL] OIDC redirect URL (Optional). The default oidc-redirect-url is 'http://localhost:0/auth/callback'.") - - cmd.Flags().BoolVar(&o.DisableAmbientProviders, "oidc-disable-ambient-providers", false, - "[EXPERIMENTAL] Disable ambient OIDC providers. When true, ambient credentials will not be read") -} diff --git a/cmd/cosign/cli/options/piv_tool.go b/cmd/cosign/cli/options/piv_tool.go deleted file mode 100644 index 2196369e4..000000000 --- a/cmd/cosign/cli/options/piv_tool.go +++ /dev/null @@ -1,138 +0,0 @@ -// -// Copyright 2021 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 options - -import ( - "github.com/spf13/cobra" -) - -// PIVToolSetManagementKeyOptions is the wrapper for `piv-tool set-management-key` related options. -type PIVToolSetManagementKeyOptions struct { - OldKey string - NewKey string - RandomKey bool -} - -var _ Interface = (*PIVToolSetManagementKeyOptions)(nil) - -// AddFlags implements Interface -func (o *PIVToolSetManagementKeyOptions) AddFlags(cmd *cobra.Command) { - cmd.Flags().StringVar(&o.OldKey, "old-key", "", - "existing management key, uses default if empty") - - cmd.Flags().StringVar(&o.NewKey, "new-key", "", - "new management key, uses default if empty") - - cmd.Flags().BoolVar(&o.RandomKey, "random-management-key", false, - "if set to true, generates a new random management key and deletes it after") -} - -// PIVToolSetPINOptions is the wrapper for `piv-tool set-pin` related options. -type PIVToolSetPINOptions struct { - OldPIN string - NewPIN string -} - -var _ Interface = (*PIVToolSetPINOptions)(nil) - -// AddFlags implements Interface -func (o *PIVToolSetPINOptions) AddFlags(cmd *cobra.Command) { - cmd.Flags().StringVar(&o.OldPIN, "old-pin", "", - "existing PIN, uses default if empty") - - cmd.Flags().StringVar(&o.NewPIN, "new-pin", "", - "new PIN, uses default if empty") -} - -// PIVToolSetPUKOptions is the wrapper for `piv-tool set-puk` related options. -type PIVToolSetPUKOptions struct { - OldPUK string - NewPUK string -} - -var _ Interface = (*PIVToolSetPUKOptions)(nil) - -// AddFlags implements Interface -func (o *PIVToolSetPUKOptions) AddFlags(cmd *cobra.Command) { - cmd.Flags().StringVar(&o.OldPUK, "old-puk", "", - "existing PUK, uses default if empty") - - cmd.Flags().StringVar(&o.NewPUK, "new-puk", "", - "new PUK, uses default if empty") -} - -// PIVToolUnblockOptions is the wrapper for `piv-tool unblock` related options. -type PIVToolUnblockOptions struct { - PUK string - NewPIN string -} - -var _ Interface = (*PIVToolUnblockOptions)(nil) - -// AddFlags implements Interface -func (o *PIVToolUnblockOptions) AddFlags(cmd *cobra.Command) { - cmd.Flags().StringVar(&o.PUK, "puk", "", - "existing PUK, uses default if empty") - - cmd.Flags().StringVar(&o.NewPIN, "new-PIN", "", - "new PIN, uses default if empty") -} - -// PIVToolAttestationOptions is the wrapper for `piv-tool attestation` related options. -type PIVToolAttestationOptions struct { - Output string - Slot string -} - -var _ Interface = (*PIVToolAttestationOptions)(nil) - -// AddFlags implements Interface -func (o *PIVToolAttestationOptions) AddFlags(cmd *cobra.Command) { - cmd.Flags().StringVarP(&o.Output, "output", "o", "text", - "format to output attestation information in. (text|json)") - - cmd.Flags().StringVar(&o.Slot, "slot", "", - "Slot to use for generated key (authentication|signature|card-authentication|key-management)") -} - -// PIVToolGenerateKeyOptions is the wrapper for `piv-tool generate-key` related options. -type PIVToolGenerateKeyOptions struct { - ManagementKey string - RandomKey bool - Slot string - PINPolicy string - TouchPolicy string -} - -var _ Interface = (*PIVToolGenerateKeyOptions)(nil) - -// AddFlags implements Interface -func (o *PIVToolGenerateKeyOptions) AddFlags(cmd *cobra.Command) { - cmd.Flags().StringVar(&o.ManagementKey, "management-key", "", - "management key, uses default if empty") - - cmd.Flags().BoolVar(&o.RandomKey, "random-management-key", false, - "if set to true, generates a new random management key and deletes it after") - - cmd.Flags().StringVar(&o.Slot, "slot", "", - "Slot to use for generated key (authentication|signature|card-authentication|key-management)") - - cmd.Flags().StringVar(&o.PINPolicy, "pin-policy", "", - "PIN policy for slot (never|once|always)") - - cmd.Flags().StringVar(&o.TouchPolicy, "touch-policy", "", - "Touch policy for slot (never|always|cached)") -} diff --git a/cmd/cosign/cli/options/pkcs11_tool.go b/cmd/cosign/cli/options/pkcs11_tool.go deleted file mode 100644 index b18aacfa9..000000000 --- a/cmd/cosign/cli/options/pkcs11_tool.go +++ /dev/null @@ -1,54 +0,0 @@ -// -// Copyright 2021 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 options - -import ( - "github.com/spf13/cobra" -) - -// PKCS11ToolListTokens is the wrapper for `pkcs11-tool list-tokens` related options. -type PKCS11ToolListTokensOptions struct { - ModulePath string -} - -var _ Interface = (*PKCS11ToolListTokensOptions)(nil) - -// AddFlags implements Interface -func (o *PKCS11ToolListTokensOptions) AddFlags(cmd *cobra.Command) { - cmd.Flags().StringVar(&o.ModulePath, "module-path", "", - "absolute path to the PKCS11 module") -} - -// PKCS11ToolListKeysUrisOptions is the wrapper for `pkcs11-tool list-keys-uris` related options. -type PKCS11ToolListKeysUrisOptions struct { - ModulePath string - SlotID uint - Pin string -} - -var _ Interface = (*PKCS11ToolListKeysUrisOptions)(nil) - -// AddFlags implements Interface -func (o *PKCS11ToolListKeysUrisOptions) AddFlags(cmd *cobra.Command) { - cmd.Flags().StringVar(&o.ModulePath, "module-path", "", - "absolute path to the PKCS11 module") - - cmd.Flags().UintVar(&o.SlotID, "slot-id", 0, - "id of the PKCS11 slot, uses 0 if empty") - - cmd.Flags().StringVar(&o.Pin, "pin", "", - "pin of the PKCS11 slot, uses environment variable COSIGN_PKCS11_PIN if empty") -} diff --git a/cmd/cosign/cli/options/policy.go b/cmd/cosign/cli/options/policy.go deleted file mode 100644 index 124144029..000000000 --- a/cmd/cosign/cli/options/policy.go +++ /dev/null @@ -1,82 +0,0 @@ -// -// Copyright 2021 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 options - -import ( - "github.com/spf13/cobra" -) - -// PolicyInitOptions is the top level wrapper for the policy-init command. -type PolicyInitOptions struct { - ImageRef string - Maintainers []string - Issuer string - Threshold int - Expires int - OutFile string - Registry RegistryOptions -} - -var _ Interface = (*PolicyInitOptions)(nil) - -// AddFlags implements Interface -func (o *PolicyInitOptions) AddFlags(cmd *cobra.Command) { - cmd.Flags().StringVar(&o.ImageRef, "namespace", "ns", - "registry namespace that the root policy belongs to") - - cmd.Flags().StringVar(&o.OutFile, "out", "o", - "output policy locally") - - cmd.Flags().StringVar(&o.Issuer, "issuer", "", - "trusted issuer to use for identity tokens, e.g. https://accounts.google.com") - - cmd.Flags().IntVar(&o.Threshold, "threshold", 1, - "threshold for root policy signers") - - cmd.Flags().StringSliceVarP(&o.Maintainers, "maintainers", "m", nil, - "list of maintainers to add to the root policy") - - cmd.Flags().IntVar(&o.Expires, "expires", 0, - "total expire duration in days") - - o.Registry.AddFlags(cmd) -} - -type PolicySignOptions struct { - ImageRef string - OutFile string - Registry RegistryOptions - Fulcio FulcioOptions - Rekor RekorOptions - - OIDC OIDCOptions -} - -var _ Interface = (*PolicySignOptions)(nil) - -// AddFlags implements Interface -func (o *PolicySignOptions) AddFlags(cmd *cobra.Command) { - cmd.Flags().StringVar(&o.ImageRef, "namespace", "ns", - "registry namespace that the root policy belongs to") - - cmd.Flags().StringVar(&o.OutFile, "out", "o", - "output policy locally") - - o.Registry.AddFlags(cmd) - o.Fulcio.AddFlags(cmd) - o.Rekor.AddFlags(cmd) - o.OIDC.AddFlags(cmd) -} diff --git a/cmd/cosign/cli/options/public_key.go b/cmd/cosign/cli/options/public_key.go deleted file mode 100644 index cbb0f0e3c..000000000 --- a/cmd/cosign/cli/options/public_key.go +++ /dev/null @@ -1,40 +0,0 @@ -// -// Copyright 2021 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 options - -import ( - "github.com/spf13/cobra" -) - -// PublicKeyOptions is the top level wrapper for the public-key command. -type PublicKeyOptions struct { - Key string - SecurityKey SecurityKeyOptions - OutFile string -} - -var _ Interface = (*PublicKeyOptions)(nil) - -// AddFlags implements Interface -func (o *PublicKeyOptions) AddFlags(cmd *cobra.Command) { - o.SecurityKey.AddFlags(cmd) - - cmd.Flags().StringVar(&o.Key, "key", "", - "path to the private key file, KMS URI or Kubernetes Secret") - - cmd.Flags().StringVar(&o.OutFile, "outfile", "", - "path to a payload file to use rather than generating one") -} diff --git a/cmd/cosign/cli/options/registry.go b/cmd/cosign/cli/options/registry.go deleted file mode 100644 index 69b181c5b..000000000 --- a/cmd/cosign/cli/options/registry.go +++ /dev/null @@ -1,99 +0,0 @@ -// Copyright 2021 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 options - -import ( - "context" - "crypto/tls" - "io/ioutil" - "net/http" - - ecr "github.com/awslabs/amazon-ecr-credential-helper/ecr-login" - "github.com/chrismellard/docker-credential-acr-env/pkg/credhelper" - "github.com/google/go-containerregistry/pkg/authn" - "github.com/google/go-containerregistry/pkg/authn/github" - "github.com/google/go-containerregistry/pkg/name" - "github.com/google/go-containerregistry/pkg/v1/google" - "github.com/google/go-containerregistry/pkg/v1/remote" - ociremote "github.com/sigstore/policy-controller/pkg/oci/remote" - "github.com/spf13/cobra" -) - -// Keychain is an alias of authn.Keychain to expose this configuration option to consumers of this lib -type Keychain = authn.Keychain - -// RegistryOptions is the wrapper for the registry options. -type RegistryOptions struct { - AllowInsecure bool - KubernetesKeychain bool - RefOpts ReferenceOptions - Keychain Keychain -} - -var _ Interface = (*RegistryOptions)(nil) - -// AddFlags implements Interface -func (o *RegistryOptions) AddFlags(cmd *cobra.Command) { - cmd.Flags().BoolVar(&o.AllowInsecure, "allow-insecure-registry", false, - "whether to allow insecure connections to registries. Don't use this for anything but testing") - - cmd.Flags().BoolVar(&o.KubernetesKeychain, "k8s-keychain", false, - "whether to use the kubernetes keychain instead of the default keychain (supports workload identity).") - - o.RefOpts.AddFlags(cmd) -} - -func (o *RegistryOptions) ClientOpts(ctx context.Context) ([]ociremote.Option, error) { - opts := []ociremote.Option{ociremote.WithRemoteOptions(o.GetRegistryClientOpts(ctx)...)} - if o.RefOpts.TagPrefix != "" { - opts = append(opts, ociremote.WithPrefix(o.RefOpts.TagPrefix)) - } - targetRepoOverride, err := ociremote.GetEnvTargetRepository() - if err != nil { - return nil, err - } - if (targetRepoOverride != name.Repository{}) { - opts = append(opts, ociremote.WithTargetRepository(targetRepoOverride)) - } - return opts, nil -} - -func (o *RegistryOptions) GetRegistryClientOpts(ctx context.Context) []remote.Option { - opts := []remote.Option{ - remote.WithContext(ctx), - remote.WithUserAgent(UserAgent()), - } - - switch { - case o.Keychain != nil: - opts = append(opts, remote.WithAuthFromKeychain(o.Keychain)) - case o.KubernetesKeychain: - kc := authn.NewMultiKeychain( - authn.DefaultKeychain, - google.Keychain, - authn.NewKeychainFromHelper(ecr.NewECRHelper(ecr.WithLogger(ioutil.Discard))), - authn.NewKeychainFromHelper(credhelper.NewACRCredentialsHelper()), - github.Keychain, - ) - opts = append(opts, remote.WithAuthFromKeychain(kc)) - default: - opts = append(opts, remote.WithAuthFromKeychain(authn.DefaultKeychain)) - } - - if o.AllowInsecure { - opts = append(opts, remote.WithTransport(&http.Transport{TLSClientConfig: &tls.Config{InsecureSkipVerify: true}})) // #nosec G402 - } - return opts -} diff --git a/cmd/cosign/cli/options/security_key.go b/cmd/cosign/cli/options/security_key.go deleted file mode 100644 index 6cf121b71..000000000 --- a/cmd/cosign/cli/options/security_key.go +++ /dev/null @@ -1,37 +0,0 @@ -// -// Copyright 2021 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 options - -import ( - "github.com/spf13/cobra" -) - -// SecurityKeyOptions is the wrapper for security key related options. -type SecurityKeyOptions struct { - Use bool - Slot string -} - -var _ Interface = (*SecurityKeyOptions)(nil) - -// AddFlags implements Interface -func (o *SecurityKeyOptions) AddFlags(cmd *cobra.Command) { - cmd.Flags().BoolVar(&o.Use, "sk", false, - "whether to use a hardware security key") - - cmd.Flags().StringVar(&o.Slot, "slot", "", - "security key slot to use for generated key (default: signature) (authentication|signature|card-authentication|key-management)") -} diff --git a/cmd/cosign/cli/options/sign.go b/cmd/cosign/cli/options/sign.go deleted file mode 100644 index e22482b67..000000000 --- a/cmd/cosign/cli/options/sign.go +++ /dev/null @@ -1,87 +0,0 @@ -// -// Copyright 2021 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 options - -import ( - "github.com/spf13/cobra" -) - -// SignOptions is the top level wrapper for the sign command. -type SignOptions struct { - Key string - Cert string - CertChain string - Upload bool - Output string // deprecated: TODO remove when the output flag is fully deprecated - OutputSignature string // TODO: this should be the root output file arg. - OutputCertificate string - PayloadPath string - Force bool - Recursive bool - Attachment string - - Rekor RekorOptions - Fulcio FulcioOptions - OIDC OIDCOptions - SecurityKey SecurityKeyOptions - AnnotationOptions - Registry RegistryOptions -} - -var _ Interface = (*SignOptions)(nil) - -// AddFlags implements Interface -func (o *SignOptions) AddFlags(cmd *cobra.Command) { - o.Rekor.AddFlags(cmd) - o.Fulcio.AddFlags(cmd) - o.OIDC.AddFlags(cmd) - o.SecurityKey.AddFlags(cmd) - o.AnnotationOptions.AddFlags(cmd) - o.Registry.AddFlags(cmd) - - cmd.Flags().StringVar(&o.Key, "key", "", - "path to the private key file, KMS URI or Kubernetes Secret") - - cmd.Flags().StringVar(&o.Cert, "certificate", "", - "path to the X.509 certificate in PEM format to include in the OCI Signature") - - cmd.Flags().StringVar(&o.CertChain, "certificate-chain", "", - "path to a list of CA X.509 certificates in PEM format which will be needed "+ - "when building the certificate chain for the signing certificate. "+ - "Must start with the parent intermediate CA certificate of the "+ - "signing certificate and end with the root certificate. Included in the OCI Signature") - - cmd.Flags().BoolVar(&o.Upload, "upload", true, - "whether to upload the signature") - - cmd.Flags().StringVar(&o.OutputSignature, "output-signature", "", - "write the signature to FILE") - - cmd.Flags().StringVar(&o.OutputCertificate, "output-certificate", "", - "write the certificate to FILE") - - cmd.Flags().StringVar(&o.PayloadPath, "payload", "", - "path to a payload file to use rather than generating one") - - cmd.Flags().BoolVarP(&o.Force, "force", "f", false, - "skip warnings and confirmations") - - cmd.Flags().BoolVarP(&o.Recursive, "recursive", "r", false, - "if a multi-arch image is specified, additionally sign each discrete image") - - cmd.Flags().StringVar(&o.Attachment, "attachment", "", - "related image attachment to sign (sbom), default none") -} diff --git a/cmd/cosign/cli/options/signblob.go b/cmd/cosign/cli/options/signblob.go deleted file mode 100644 index 49381daa8..000000000 --- a/cmd/cosign/cli/options/signblob.go +++ /dev/null @@ -1,65 +0,0 @@ -// -// Copyright 2021 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 options - -import ( - "github.com/spf13/cobra" -) - -// SignBlobOptions is the top level wrapper for the sign-blob command. -// The new output-certificate flag is only in use when COSIGN_EXPERIMENTAL is enabled -type SignBlobOptions struct { - Key string - Base64Output bool - Output string // deprecated: TODO remove when the output flag is fully deprecated - OutputSignature string // TODO: this should be the root output file arg. - OutputCertificate string - SecurityKey SecurityKeyOptions - Fulcio FulcioOptions - Rekor RekorOptions - OIDC OIDCOptions - Registry RegistryOptions - BundlePath string -} - -var _ Interface = (*SignBlobOptions)(nil) - -// AddFlags implements Interface -func (o *SignBlobOptions) AddFlags(cmd *cobra.Command) { - o.SecurityKey.AddFlags(cmd) - o.Fulcio.AddFlags(cmd) - o.Rekor.AddFlags(cmd) - o.OIDC.AddFlags(cmd) - o.Registry.AddFlags(cmd) - - cmd.Flags().StringVar(&o.Key, "key", "", - "path to the private key file, KMS URI or Kubernetes Secret") - - cmd.Flags().BoolVar(&o.Base64Output, "b64", true, - "whether to base64 encode the output") - - cmd.Flags().StringVar(&o.OutputSignature, "output-signature", "", - "write the signature to FILE") - - // TODO: remove when output flag is fully deprecated - cmd.Flags().StringVar(&o.Output, "output", "", "write the signature to FILE") - - cmd.Flags().StringVar(&o.OutputCertificate, "output-certificate", "", - "write the certificate to FILE") - - cmd.Flags().StringVar(&o.BundlePath, "bundle", "", - "write everything required to verify the blob to a FILE") -} diff --git a/cmd/cosign/cli/options/tree.go b/cmd/cosign/cli/options/tree.go deleted file mode 100644 index a015d8949..000000000 --- a/cmd/cosign/cli/options/tree.go +++ /dev/null @@ -1,28 +0,0 @@ -// Copyright 2022 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 options - -import "github.com/spf13/cobra" - -type TreeOptions struct { - Registry RegistryOptions - CleanType string -} - -var _ Interface = (*TreeOptions)(nil) - -func (c *TreeOptions) AddFlags(cmd *cobra.Command) { - c.Registry.AddFlags(cmd) -} diff --git a/cmd/cosign/cli/options/triangulate.go b/cmd/cosign/cli/options/triangulate.go deleted file mode 100644 index 5a60b38e9..000000000 --- a/cmd/cosign/cli/options/triangulate.go +++ /dev/null @@ -1,36 +0,0 @@ -// -// Copyright 2021 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 options - -import ( - "github.com/spf13/cobra" -) - -// TriangulateOptions is the top level wrapper for the triangulate command. -type TriangulateOptions struct { - Type string - Registry RegistryOptions -} - -var _ Interface = (*TriangulateOptions)(nil) - -// AddFlags implements Interface -func (o *TriangulateOptions) AddFlags(cmd *cobra.Command) { - o.Registry.AddFlags(cmd) - - cmd.Flags().StringVar(&o.Type, "type", "signature", - "related attachment to triangulate (attestation|sbom|signature), default signature") -} diff --git a/cmd/cosign/cli/options/upload.go b/cmd/cosign/cli/options/upload.go deleted file mode 100644 index 9d7b77ac9..000000000 --- a/cmd/cosign/cli/options/upload.go +++ /dev/null @@ -1,55 +0,0 @@ -// -// Copyright 2021 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 options - -import ( - "github.com/spf13/cobra" -) - -// UploadBlobOptions is the top level wrapper for the `upload blob` command. -type UploadBlobOptions struct { - ContentType string - Files FilesOptions - Registry RegistryOptions -} - -var _ Interface = (*UploadBlobOptions)(nil) - -// AddFlags implements Interface -func (o *UploadBlobOptions) AddFlags(cmd *cobra.Command) { - o.Registry.AddFlags(cmd) - o.Files.AddFlags(cmd) - - cmd.Flags().StringVar(&o.ContentType, "ct", "", - "content type to set") -} - -// UploadWASMOptions is the top level wrapper for the `upload wasm` command. -type UploadWASMOptions struct { - File string - Registry RegistryOptions -} - -var _ Interface = (*UploadWASMOptions)(nil) - -// AddFlags implements Interface -func (o *UploadWASMOptions) AddFlags(cmd *cobra.Command) { - o.Registry.AddFlags(cmd) - - cmd.Flags().StringVarP(&o.File, "file", "f", "", - "path to the wasm file to upload") - _ = cmd.MarkFlagRequired("file") -} diff --git a/cmd/cosign/cli/options/verify.go b/cmd/cosign/cli/options/verify.go deleted file mode 100644 index 869197b33..000000000 --- a/cmd/cosign/cli/options/verify.go +++ /dev/null @@ -1,155 +0,0 @@ -// -// Copyright 2021 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 options - -import ( - "github.com/spf13/cobra" -) - -// VerifyOptions is the top level wrapper for the `verify` command. -type VerifyOptions struct { - Key string - CheckClaims bool - Attachment string - Output string - SignatureRef string - LocalImage bool - - SecurityKey SecurityKeyOptions - CertVerify CertVerifyOptions - Rekor RekorOptions - Registry RegistryOptions - SignatureDigest SignatureDigestOptions - AnnotationOptions -} - -var _ Interface = (*VerifyOptions)(nil) - -// AddFlags implements Interface -func (o *VerifyOptions) AddFlags(cmd *cobra.Command) { - o.SecurityKey.AddFlags(cmd) - o.Rekor.AddFlags(cmd) - o.CertVerify.AddFlags(cmd) - o.Registry.AddFlags(cmd) - o.SignatureDigest.AddFlags(cmd) - o.AnnotationOptions.AddFlags(cmd) - - cmd.Flags().StringVar(&o.Key, "key", "", - "path to the public key file, KMS URI or Kubernetes Secret") - - cmd.Flags().BoolVar(&o.CheckClaims, "check-claims", true, - "whether to check the claims found") - - cmd.Flags().StringVar(&o.Attachment, "attachment", "", - "related image attachment to sign (sbom), default none") - - cmd.Flags().StringVarP(&o.Output, "output", "o", "json", - "output format for the signing image information (json|text)") - - cmd.Flags().StringVar(&o.SignatureRef, "signature", "", - "signature content or path or remote URL") - - cmd.Flags().BoolVar(&o.LocalImage, "local-image", false, - "whether the specified image is a path to an image saved locally via 'cosign save'") -} - -// VerifyAttestationOptions is the top level wrapper for the `verify attestation` command. -type VerifyAttestationOptions struct { - Key string - CheckClaims bool - Output string - - SecurityKey SecurityKeyOptions - Rekor RekorOptions - CertVerify CertVerifyOptions - Registry RegistryOptions - Predicate PredicateRemoteOptions - Policies []string - LocalImage bool -} - -var _ Interface = (*VerifyAttestationOptions)(nil) - -// AddFlags implements Interface -func (o *VerifyAttestationOptions) AddFlags(cmd *cobra.Command) { - o.SecurityKey.AddFlags(cmd) - o.Rekor.AddFlags(cmd) - o.CertVerify.AddFlags(cmd) - o.Registry.AddFlags(cmd) - o.Predicate.AddFlags(cmd) - - cmd.Flags().StringVar(&o.Key, "key", "", - "path to the public key file, KMS URI or Kubernetes Secret") - - cmd.Flags().BoolVar(&o.CheckClaims, "check-claims", true, - "whether to check the claims found") - - cmd.Flags().StringSliceVar(&o.Policies, "policy", nil, - "specify CUE or Rego files will be using for validation") - - cmd.Flags().StringVarP(&o.Output, "output", "o", "json", - "output format for the signing image information (json|text)") - - cmd.Flags().BoolVar(&o.LocalImage, "local-image", false, - "whether the specified image is a path to an image saved locally via 'cosign save'") -} - -// VerifyBlobOptions is the top level wrapper for the `verify blob` command. -type VerifyBlobOptions struct { - Key string - Signature string - BundlePath string - - SecurityKey SecurityKeyOptions - CertVerify CertVerifyOptions - Rekor RekorOptions - Registry RegistryOptions -} - -var _ Interface = (*VerifyBlobOptions)(nil) - -// AddFlags implements Interface -func (o *VerifyBlobOptions) AddFlags(cmd *cobra.Command) { - o.SecurityKey.AddFlags(cmd) - o.Rekor.AddFlags(cmd) - o.CertVerify.AddFlags(cmd) - o.Registry.AddFlags(cmd) - - cmd.Flags().StringVar(&o.Key, "key", "", - "path to the public key file, KMS URI or Kubernetes Secret") - - cmd.Flags().StringVar(&o.Signature, "signature", "", - "signature content or path or remote URL") - - cmd.Flags().StringVar(&o.BundlePath, "bundle", "", - "path to bundle FILE") -} - -// VerifyBlobOptions is the top level wrapper for the `verify blob` command. -type VerifyDockerfileOptions struct { - VerifyOptions - BaseImageOnly bool -} - -var _ Interface = (*VerifyDockerfileOptions)(nil) - -// AddFlags implements Interface -func (o *VerifyDockerfileOptions) AddFlags(cmd *cobra.Command) { - o.VerifyOptions.AddFlags(cmd) - - cmd.Flags().BoolVar(&o.BaseImageOnly, "base-image-only", false, - "only verify the base image (the last FROM image in the Dockerfile)") -} diff --git a/cmd/cosign/cli/piv_tool.go b/cmd/cosign/cli/piv_tool.go deleted file mode 100644 index 33e3f9bb5..000000000 --- a/cmd/cosign/cli/piv_tool.go +++ /dev/null @@ -1,180 +0,0 @@ -//go:build pivkey && cgo -// +build pivkey,cgo - -// Copyright 2021 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 cli - -import ( - "encoding/json" - - "github.com/spf13/cobra" - - "github.com/sigstore/policy-controller/cmd/cosign/cli/options" - "github.com/sigstore/policy-controller/cmd/cosign/cli/pivcli" -) - -var pivToolForce bool - -func PIVTool() *cobra.Command { - cmd := &cobra.Command{ - Use: "piv-tool", - Short: "Provides utilities for managing a hardware token", - } - - cmd.AddCommand( - pivToolSetManagementKey(), - pivToolSetPIN(), - pivToolSetPUK(), - pivToolUnblock(), - pivToolAttestation(), - pivToolGenerateKey(), - pivToolResetKey(), - ) - - // TODO: drop -f in favor of --no-input only - // TODO: use the force flag. - cmd.PersistentFlags().BoolVarP(&pivToolForce, "no-input", "f", false, - "skip warnings and confirmations") - - return cmd -} - -func pivToolSetManagementKey() *cobra.Command { - o := &options.PIVToolSetManagementKeyOptions{} - - cmd := &cobra.Command{ - Use: "set-management-key", - Short: "sets the management key of a hardware token", - Args: cobra.ExactArgs(0), - RunE: func(cmd *cobra.Command, args []string) error { - return pivcli.SetManagementKeyCmd(cmd.Context(), o.OldKey, o.NewKey, o.RandomKey) - }, - } - - o.AddFlags(cmd) - - return cmd -} - -func pivToolSetPIN() *cobra.Command { - o := &options.PIVToolSetPINOptions{} - - cmd := &cobra.Command{ - Use: "set-pin", - Short: "sets the PIN on a hardware token", - Args: cobra.ExactArgs(0), - RunE: func(cmd *cobra.Command, args []string) error { - return pivcli.SetPinCmd(cmd.Context(), o.OldPIN, o.NewPIN) - }, - } - - o.AddFlags(cmd) - - return cmd -} - -func pivToolSetPUK() *cobra.Command { - o := &options.PIVToolSetPUKOptions{} - - cmd := &cobra.Command{ - Use: "set-puk", - Short: "sets the PUK on a hardware token", - Args: cobra.ExactArgs(0), - RunE: func(cmd *cobra.Command, args []string) error { - return pivcli.SetPukCmd(cmd.Context(), o.OldPUK, o.NewPUK) - }, - } - - o.AddFlags(cmd) - - return cmd -} - -func pivToolUnblock() *cobra.Command { - o := &options.PIVToolUnblockOptions{} - - cmd := &cobra.Command{ - Use: "unblock", - Short: "unblocks the hardware token, sets a new PIN", - Args: cobra.ExactArgs(0), - RunE: func(cmd *cobra.Command, args []string) error { - return pivcli.UnblockCmd(cmd.Context(), o.PUK, o.NewPIN) - }, - } - - o.AddFlags(cmd) - - return cmd -} - -func pivToolAttestation() *cobra.Command { - o := &options.PIVToolAttestationOptions{} - - cmd := &cobra.Command{ - Use: "attestation", - Short: "attestation contains commands to manage a hardware token", - Args: cobra.ExactArgs(0), - RunE: func(cmd *cobra.Command, args []string) error { - a, err := pivcli.AttestationCmd(cmd.Context(), o.Slot) - switch o.Output { - case "text": - a.Output(cmd.OutOrStdout(), cmd.OutOrStderr()) - case "json": - b, err := json.Marshal(a) - if err != nil { - return err - } - cmd.Println(string(b)) - } - return err - }, - } - - o.AddFlags(cmd) - - return cmd -} - -func pivToolGenerateKey() *cobra.Command { - o := &options.PIVToolGenerateKeyOptions{} - - cmd := &cobra.Command{ - Use: "generate-key", - Short: "generate-key generates a new signing key on the hardware token", - Args: cobra.ExactArgs(0), - RunE: func(cmd *cobra.Command, args []string) error { - return pivcli.GenerateKeyCmd(cmd.Context(), o.ManagementKey, o.RandomKey, - o.Slot, o.PINPolicy, o.TouchPolicy) - }, - } - - o.AddFlags(cmd) - - return cmd -} - -func pivToolResetKey() *cobra.Command { - cmd := &cobra.Command{ - Use: "reset", - Short: "reset resets the hardware token completely", - Args: cobra.ExactArgs(0), - RunE: func(cmd *cobra.Command, args []string) error { - return pivcli.ResetKeyCmd(cmd.Context()) - }, - } - - return cmd -} diff --git a/cmd/cosign/cli/piv_tool_disabled.go b/cmd/cosign/cli/piv_tool_disabled.go deleted file mode 100644 index 36b31c384..000000000 --- a/cmd/cosign/cli/piv_tool_disabled.go +++ /dev/null @@ -1,29 +0,0 @@ -//go:build !pivkey || !cgo -// +build !pivkey !cgo - -// Copyright 2021 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 cli - -import ( - "github.com/spf13/cobra" -) - -func PIVTool() *cobra.Command { - return &cobra.Command{ - Use: "piv-tool", - Short: "This cosign was not built with piv-tool support!", - } -} diff --git a/cmd/cosign/cli/pivcli/commands.go b/cmd/cosign/cli/pivcli/commands.go deleted file mode 100644 index a3dd3a05b..000000000 --- a/cmd/cosign/cli/pivcli/commands.go +++ /dev/null @@ -1,355 +0,0 @@ -//go:build pivkey && cgo -// +build pivkey,cgo - -// Copyright 2021 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 pivcli - -import ( - "context" - "crypto/rand" - "crypto/x509" - "encoding/pem" - "errors" - "flag" - "fmt" - "io" - "os" - "strings" - - "github.com/go-piv/piv-go/piv" - "github.com/manifoldco/promptui" - - "github.com/sigstore/policy-controller/pkg/cosign/pivkey" -) - -func SetManagementKeyCmd(_ context.Context, oldKey, newKey string, randomKey bool) error { - yk, err := pivkey.GetKey() - if err != nil { - return err - } - defer yk.Close() - - oldBytes, err := keyBytes(oldKey) - if err != nil { - return err - } - var newBytes *[24]byte - if randomKey { - if !Confirm("Resetting management key to random value. You must factory reset the device to change this value") { - return nil - } - newBytes, err = randomManagementKey() - if err != nil { - return err - } - } else { - newBytes, err = keyBytes(newKey) - if err != nil { - return err - } - } - if !Confirm("Setting new management key. This will overwrite the previous key.") { - return nil - } - return yk.SetManagementKey(*oldBytes, *newBytes) -} - -func SetPukCmd(_ context.Context, oldPuk, newPuk string) error { - yk, err := pivkey.GetKey() - if err != nil { - return err - } - defer yk.Close() - if oldPuk == "" { - oldPuk = piv.DefaultPUK - } - if newPuk == "" { - newPuk = piv.DefaultPUK - } - if !Confirm("Setting new PUK. This will overwrite the previous PUK.") { - return nil - } - return yk.SetPUK(oldPuk, newPuk) -} - -func UnblockCmd(_ context.Context, oldPuk, newPin string) error { - yk, err := pivkey.GetKey() - if err != nil { - return err - } - defer yk.Close() - if oldPuk == "" { - oldPuk = piv.DefaultPUK - } - if newPin == "" { - newPin = piv.DefaultPIN - } - if !Confirm("Unblocking the device. This will set a new pin.") { - return nil - } - return yk.Unblock(oldPuk, newPin) -} - -func SetPinCmd(_ context.Context, oldPin, newPin string) error { - yk, err := pivkey.GetKey() - if err != nil { - return err - } - defer yk.Close() - - if oldPin == "" { - oldPin = piv.DefaultPIN - } - if newPin == "" { - newPin = piv.DefaultPIN - } - if !Confirm("Setting new pin. This will overwrite the previous pin.") { - return nil - } - return yk.SetPIN(oldPin, newPin) -} - -type Attestations struct { - // Skip these for JSON, use the byte form instead - DeviceCert *x509.Certificate `json:"-"` - KeyCert *x509.Certificate `json:"-"` - DeviceCertPem string - KeyCertPem string - KeyAttestation *piv.Attestation -} - -func (a *Attestations) Output(stdout, stderr io.Writer) { - fmt.Fprintln(stderr, "Printing device attestation certificate") - b := pem.EncodeToMemory(&pem.Block{ - Type: "CERTIFICATE", - Bytes: a.DeviceCert.Raw, - }) - fmt.Fprintln(stdout, string(b)) - - fmt.Fprintln(stderr, "Printing key attestation certificate") - b = pem.EncodeToMemory(&pem.Block{ - Type: "CERTIFICATE", - Bytes: a.KeyCert.Raw, - }) - fmt.Fprintln(stdout, string(b)) - - fmt.Fprintln(stderr, "Verifying certificates...") - - fmt.Fprintln(stderr, "Verified ok") - fmt.Println() - - fmt.Fprintln(stderr, "Device info:") - fmt.Fprintln(stdout, " Issuer:", a.DeviceCert.Issuer) - fmt.Fprintln(stdout, " Form factor:", formFactorString(a.KeyAttestation.Formfactor)) - fmt.Fprintln(stdout, " PIN Policy:", pinPolicyStr(a.KeyAttestation.PINPolicy)) - - fmt.Fprintf(stdout, " Serial number: %d\n", a.KeyAttestation.Serial) - fmt.Fprintf(stdout, " Version: %d.%d.%d\n", a.KeyAttestation.Version.Major, a.KeyAttestation.Version.Minor, a.KeyAttestation.Version.Patch) -} - -func AttestationCmd(_ context.Context, slotArg string) (*Attestations, error) { - yk, err := pivkey.GetKeyWithSlot(slotArg) - if err != nil { - return nil, err - } - defer yk.Close() - deviceCert, err := yk.GetAttestationCertificate() - if err != nil { - return nil, err - } - - keyCert, err := yk.Attest() - if err != nil { - return nil, err - } - - a, err := piv.Verify(deviceCert, keyCert) - if err != nil { - return nil, err - } - - ret := &Attestations{ - DeviceCert: deviceCert, - DeviceCertPem: toPem(deviceCert), - KeyCert: keyCert, - KeyCertPem: toPem(keyCert), - KeyAttestation: a, - } - - return ret, nil -} - -func toPem(c *x509.Certificate) string { - b := pem.EncodeToMemory(&pem.Block{ - Type: "CERTIFICATE", - Bytes: c.Raw, - }) - return string(b) -} - -func GenerateKeyCmd(ctx context.Context, managementKey string, randomKey bool, slotArg string, pinPolicyArg string, touchPolicyArg string) error { - slot := pivkey.SlotForName(slotArg) - if slot == nil { - return flag.ErrHelp - } - - pinPolicy := pivkey.PINPolicyForName(pinPolicyArg, *slot) - if pinPolicy < 0 { - return flag.ErrHelp - } - - touchPolicy := pivkey.TouchPolicyForName(pinPolicyArg, *slot) - if touchPolicy < 0 { - return flag.ErrHelp - } - - yk, err := pivkey.GetKey() - if err != nil { - return err - } - defer yk.Close() - keyBytes, err := keyBytes(managementKey) - if err != nil { - return err - } - - if randomKey { - if !Confirm("Resetting management key to random value. You must factory reset the device to change this value") { - return nil - } - newKeyBytes, err := randomManagementKey() - if err != nil { - return err - } - if err := yk.SetManagementKey(*keyBytes, *newKeyBytes); err != nil { - return err - } - keyBytes = newKeyBytes - } - - key := piv.Key{ - Algorithm: piv.AlgorithmEC256, - PINPolicy: pinPolicy, - TouchPolicy: touchPolicy, - } - if !Confirm("Generating new signing key. This will destroy any previous keys.") { - return nil - } - pubKey, err := yk.GenerateKey(*keyBytes, *slot, key) - if err != nil { - return err - } - fmt.Fprintln(os.Stderr, "Generated public key") - b, err := x509.MarshalPKIXPublicKey(pubKey) - if err != nil { - return err - } - pemBytes := pem.EncodeToMemory(&pem.Block{ - Type: "PUBLIC KEY", - Bytes: b, - }) - - fmt.Println(string(pemBytes)) - yk.Close() - - att, err := AttestationCmd(ctx, slotArg) - if err != nil { - return err - } - att.Output(os.Stdout, os.Stderr) - return nil -} - -func ResetKeyCmd(ctx context.Context) error { - yk, err := pivkey.GetKey() - if err != nil { - return err - } - defer yk.Close() - if !Confirm("Resetting key to factory defaults. This will destroy all values on device.") { - return nil - } - - return yk.Reset() -} - -func keyBytes(s string) (*[24]byte, error) { - if s == "" { - return &piv.DefaultManagementKey, nil - } - if len(s) > 24 { - return nil, errors.New("key too long, must be <24 characters") - } - ret := [24]byte{} - copy(ret[:], s) - return &ret, nil -} - -var Confirm = func(p string) bool { - prompt := promptui.Prompt{ - Label: p, - IsConfirm: true, - } - - result, err := prompt.Run() - if err != nil { - fmt.Println(err) - return false - } - return strings.ToLower(result) == "y" -} - -func randomManagementKey() (*[24]byte, error) { - var newKeyBytes [24]byte - n, err := io.ReadFull(rand.Reader, newKeyBytes[:]) - if err != nil { - return nil, err - } - if n != len(newKeyBytes) { - return nil, errors.New("short read from random") - } - return &newKeyBytes, nil -} - -func formFactorString(ff piv.Formfactor) string { - switch ff { - case piv.FormfactorUSBAKeychain: - return "USB A Keychain" - case piv.FormfactorUSBANano: - return "USB A Nano" - case piv.FormfactorUSBCKeychain: - return "USB C Keychain" - case piv.FormfactorUSBCNano: - return "USB C Nano" - case piv.FormfactorUSBCLightningKeychain: - return "USB C Lighting Keychain" - default: - return fmt.Sprintf("unknown: %d", ff) - } -} - -func pinPolicyStr(pp piv.PINPolicy) string { - switch pp { - case piv.PINPolicyAlways: - return "Always" - case piv.PINPolicyNever: - return "Never" - case piv.PINPolicyOnce: - return "Once" - default: - return "unknown" - } -} diff --git a/cmd/cosign/cli/pkcs11_tool.go b/cmd/cosign/cli/pkcs11_tool.go deleted file mode 100644 index 618d85d7d..000000000 --- a/cmd/cosign/cli/pkcs11_tool.go +++ /dev/null @@ -1,80 +0,0 @@ -//go:build pkcs11key -// +build pkcs11key - -// Copyright 2021 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 cli - -import ( - "github.com/spf13/cobra" - - "github.com/sigstore/policy-controller/cmd/cosign/cli/options" - "github.com/sigstore/policy-controller/cmd/cosign/cli/pkcs11cli" -) - -var pkcs11ToolForce bool - -func PKCS11Tool() *cobra.Command { - cmd := &cobra.Command{ - Use: "pkcs11-tool", - Short: "Provides utilities for retrieving information from a PKCS11 token.", - } - - cmd.AddCommand( - pkcs11ToolListTokens(), - PKCS11ToolListKeysUrisOptions(), - ) - - // TODO: drop -f in favor of --no-input only - // TODO: use the force flag. - cmd.PersistentFlags().BoolVarP(&pkcs11ToolForce, "no-input", "f", false, - "skip warnings and confirmations") - - return cmd -} - -func pkcs11ToolListTokens() *cobra.Command { - o := &options.PKCS11ToolListTokensOptions{} - - cmd := &cobra.Command{ - Use: "list-tokens", - Short: "list-tokens lists all PKCS11 tokens linked to a PKCS11 module", - Args: cobra.ExactArgs(0), - RunE: func(cmd *cobra.Command, args []string) error { - return pkcs11cli.ListTokensCmd(cmd.Context(), o.ModulePath) - }, - } - - o.AddFlags(cmd) - - return cmd -} - -func PKCS11ToolListKeysUrisOptions() *cobra.Command { - o := &options.PKCS11ToolListKeysUrisOptions{} - - cmd := &cobra.Command{ - Use: "list-keys-uris", - Short: "list-keys-uris lists URIs of all keys in a PKCS11 token", - Args: cobra.ExactArgs(0), - RunE: func(cmd *cobra.Command, args []string) error { - return pkcs11cli.ListKeysUrisCmd(cmd.Context(), o.ModulePath, o.SlotID, o.Pin) - }, - } - - o.AddFlags(cmd) - - return cmd -} diff --git a/cmd/cosign/cli/pkcs11_tool_disabled.go b/cmd/cosign/cli/pkcs11_tool_disabled.go deleted file mode 100644 index a073c37a3..000000000 --- a/cmd/cosign/cli/pkcs11_tool_disabled.go +++ /dev/null @@ -1,29 +0,0 @@ -//go:build !pkcs11key -// +build !pkcs11key - -// Copyright 2021 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 cli - -import ( - "github.com/spf13/cobra" -) - -func PKCS11Tool() *cobra.Command { - return &cobra.Command{ - Use: "pkcs11-tool", - Short: "This cosign was not built with pkcs11-tool support!", - } -} diff --git a/cmd/cosign/cli/pkcs11cli/commands.go b/cmd/cosign/cli/pkcs11cli/commands.go deleted file mode 100644 index 14b306daf..000000000 --- a/cmd/cosign/cli/pkcs11cli/commands.go +++ /dev/null @@ -1,245 +0,0 @@ -//go:build pkcs11key -// +build pkcs11key - -// Copyright 2021 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 pkcs11cli - -import ( - "context" - "encoding/hex" - "errors" - "flag" - "fmt" - "os" - "path/filepath" - "syscall" - - "github.com/miekg/pkcs11" - "github.com/sigstore/policy-controller/pkg/cosign/pkcs11key" - "golang.org/x/term" -) - -type Token struct { - Slot uint - TokenInfo pkcs11.TokenInfo -} - -type KeyInfo struct { - KeyLabel []byte - KeyID []byte - KeyURI string -} - -func GetTokens(_ context.Context, modulePath string) ([]Token, error) { - if modulePath == "" || !filepath.IsAbs(modulePath) { - return nil, flag.ErrHelp - } - - var tokens []Token - - // Initialize PKCS11 module. - p := pkcs11.New(modulePath) - if p == nil { - return nil, errors.New("failed to load PKCS11 module") - } - err := p.Initialize() - if err != nil { - return nil, fmt.Errorf("initialize PKCS11 module: %w", err) - } - defer p.Destroy() - defer p.Finalize() - - // Get list of all slots with a token, and get info of each. - slots, err := p.GetSlotList(true) - if err != nil { - return nil, fmt.Errorf("get slot list: %w", err) - } - for _, slot := range slots { - tokenInfo, err := p.GetTokenInfo(slot) - if err != nil { - continue - } - tokens = append(tokens, Token{Slot: slot, TokenInfo: tokenInfo}) - } - - return tokens, nil -} - -func GetKeysInfo(_ context.Context, modulePath string, slotID uint, pin string) ([]KeyInfo, error) { - if modulePath == "" || !filepath.IsAbs(modulePath) { - return nil, flag.ErrHelp - } - - var keysInfo []KeyInfo - - // Initialize PKCS11 module. - ctx := pkcs11.New(modulePath) - if ctx == nil { - return nil, errors.New("failed to load PKCS11 module") - } - err := ctx.Initialize() - if err != nil { - return nil, fmt.Errorf("initialize PKCS11 module: %w", err) - } - defer ctx.Destroy() - defer ctx.Finalize() - - // Get token Info. - var tokenInfo pkcs11.TokenInfo - tokenInfo, err = ctx.GetTokenInfo(uint(slotID)) - if err != nil { - return nil, fmt.Errorf("get token info: %w", err) - } - - // If pin was not given, check COSIGN_PKCS11_PIN environment variable. - if pin == "" { - pin = os.Getenv("COSIGN_PKCS11_PIN") - - // If COSIGN_PKCS11_PIN was not set, check if CKF_LOGIN_REQUIRED is set in Token Info. - // If it is, ask the user for the PIN, otherwise, do not. - if pin == "" { - if tokenInfo.Flags&pkcs11.CKF_LOGIN_REQUIRED == pkcs11.CKF_LOGIN_REQUIRED { - fmt.Fprintf(os.Stderr, "Enter PIN for PKCS11 token '%s': ", tokenInfo.Label) - // Unnecessary convert of syscall.Stdin on *nix, but Windows is a uintptr - // nolint:unconvert - b, err := term.ReadPassword(int(syscall.Stdin)) - if err != nil { - return nil, fmt.Errorf("get pin: %w", err) - } - pin = string(b) - } - } - } - - // Open a new session to the token. - session, err := ctx.OpenSession(slotID, pkcs11.CKF_SERIAL_SESSION|pkcs11.CKF_RW_SESSION) - if err != nil { - return nil, fmt.Errorf("open session: %w", err) - } - defer ctx.CloseSession(session) - - // Login user. - err = ctx.Login(session, pkcs11.CKU_USER, pin) - if err != nil { - return nil, fmt.Errorf("login: %w", err) - } - defer ctx.Logout(session) - - // Look for private keys. - maxHandlePerFind := 20 - var handles []pkcs11.ObjectHandle - findAttributes := []*pkcs11.Attribute{ - pkcs11.NewAttribute(pkcs11.CKA_CLASS, pkcs11.CKO_PRIVATE_KEY), - } - if err = ctx.FindObjectsInit(session, findAttributes); err != nil { - return nil, fmt.Errorf("init find objects: %w", err) - } - newhandles, _, err := ctx.FindObjects(session, maxHandlePerFind) - if err != nil { - return nil, fmt.Errorf("find objects: %w", err) - } - for len(newhandles) > 0 { - handles = append(handles, newhandles...) - newhandles, _, err = ctx.FindObjects(session, maxHandlePerFind) - if err != nil { - return nil, fmt.Errorf("find objects: %w", err) - } - } - err = ctx.FindObjectsFinal(session) - if err != nil { - return nil, fmt.Errorf("finalize find objects: %w", err) - } - - // For each private key, get key label and key id then construct uri. - for _, handle := range handles { - var keyInfo KeyInfo - - attributes := []*pkcs11.Attribute{ - pkcs11.NewAttribute(pkcs11.CKA_ID, nil), - pkcs11.NewAttribute(pkcs11.CKA_LABEL, nil), - } - if attributes, err = ctx.GetAttributeValue(session, handle, attributes); err != nil { - return nil, fmt.Errorf("get attributes: %w", err) - } - keyID := attributes[0].Value - keyLabel := attributes[1].Value - slotIDInt := int(slotID) - - // If the object has neither a key id nor a key label, we skip it. - if (keyID == nil || len(keyID) == 0) && (keyLabel == nil || len(keyLabel) == 0) { - continue - } - - // Construct the PKCS11 URI. - pkcs11Uri := pkcs11key.NewPkcs11UriConfigFromInput(modulePath, &slotIDInt, tokenInfo.Label, keyLabel, keyID, pin) - pkcs11UriStr, err := pkcs11Uri.Construct() - if err != nil { - return nil, fmt.Errorf("construct pkcs11 uri: %w", err) - } - - if keyLabel != nil && len(keyLabel) != 0 { - keyInfo.KeyLabel = keyLabel - } - if keyID != nil && len(keyID) != 0 { - keyInfo.KeyID = keyID - } - keyInfo.KeyURI = pkcs11UriStr - keysInfo = append(keysInfo, keyInfo) - } - - return keysInfo, nil -} - -func ListTokensCmd(ctx context.Context, modulePath string) error { - - tokens, err := GetTokens(ctx, modulePath) - if err != nil { - return err - } - - fmt.Fprintf(os.Stdout, "\nListing tokens of PKCS11 module '%s'\n", modulePath) - for _, token := range tokens { - fmt.Fprintf(os.Stdout, "Token in slot %d\n", token.Slot) - fmt.Fprintf(os.Stdout, "\tLabel: %s\n", token.TokenInfo.Label) - fmt.Fprintf(os.Stdout, "\tManufacturer: %s\n", token.TokenInfo.ManufacturerID) - fmt.Fprintf(os.Stdout, "\tModel: %s\n", token.TokenInfo.Model) - fmt.Fprintf(os.Stdout, "\tS/N: %s\n\n", token.TokenInfo.SerialNumber) - } - - return nil -} - -func ListKeysUrisCmd(ctx context.Context, modulePath string, slotID uint, pin string) error { - - keysInfo, err := GetKeysInfo(ctx, modulePath, slotID, pin) - if err != nil { - return err - } - - fmt.Fprintf(os.Stdout, "\nListing URIs of keys in slot '%d' of PKCS11 module '%s'\n", slotID, modulePath) - for i, keyInfo := range keysInfo { - fmt.Fprintf(os.Stdout, "Object %d\n", i) - if keyInfo.KeyLabel != nil && len(keyInfo.KeyLabel) != 0 { - fmt.Fprintf(os.Stdout, "\tLabel: %s\n", string(keyInfo.KeyLabel)) - } - if keyInfo.KeyID != nil && len(keyInfo.KeyID) != 0 { - fmt.Fprintf(os.Stdout, "\tID: %s\n", hex.EncodeToString(keyInfo.KeyID)) - } - fmt.Fprintf(os.Stdout, "\tURI: %s\n", keyInfo.KeyURI) - } - - return nil -} diff --git a/cmd/cosign/cli/policy_init.go b/cmd/cosign/cli/policy_init.go deleted file mode 100644 index 1e5d3b96a..000000000 --- a/cmd/cosign/cli/policy_init.go +++ /dev/null @@ -1,304 +0,0 @@ -// -// Copyright 2021 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 cli - -import ( - "bytes" - "context" - "encoding/base64" - "encoding/json" - "errors" - "fmt" - "io" - "net/mail" - "os" - "path/filepath" - "strings" - "time" - - "github.com/google/go-containerregistry/pkg/authn" - "github.com/google/go-containerregistry/pkg/name" - "github.com/google/go-containerregistry/pkg/v1/remote" - "github.com/sigstore/policy-controller/cmd/cosign/cli/options" - "github.com/sigstore/policy-controller/cmd/cosign/cli/rekor" - "github.com/sigstore/policy-controller/cmd/cosign/cli/sign" - "github.com/sigstore/policy-controller/cmd/cosign/cli/upload" - "github.com/sigstore/sigstore/pkg/cryptoutils" - - "github.com/sigstore/policy-controller/pkg/cosign" - cremote "github.com/sigstore/policy-controller/pkg/cosign/remote" - "github.com/sigstore/policy-controller/pkg/cosign/tuf" - "github.com/sigstore/policy-controller/pkg/sget" - sigs "github.com/sigstore/policy-controller/pkg/signature" - signatureoptions "github.com/sigstore/sigstore/pkg/signature/options" - "github.com/spf13/cobra" -) - -func validEmail(email string) bool { - _, err := mail.ParseAddress(email) - return err == nil -} - -func rootPath(imageRef string) string { - return filepath.Join(imageRef, "root") -} - -func Policy() *cobra.Command { - cmd := &cobra.Command{ - Use: "policy", - Short: "subcommand to manage 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 { - return cmd.Help() - }, - } - - cmd.AddCommand( - initPolicy(), - signPolicy(), - ) - - return cmd -} - -func initPolicy() *cobra.Command { - o := &options.PolicyInitOptions{} - - cmd := &cobra.Command{ - Use: "init", - Short: "generate a new keyless policy.", - Long: "init is used to generate 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.", - Example: ` - # extract public key from private key to a specified out file. - cosign policy init -ns --maintainers {email_addresses} --threshold --expires (days)`, - RunE: func(cmd *cobra.Command, args []string) error { - var publicKeys []*tuf.Key - - // Process the list of maintainers by - // 1. Ensure each entry is a correctly formatted email address - // 2. If 1 is true, then remove surplus whitespace (caused by gaps between commas) - for _, email := range o.Maintainers { - if !validEmail(email) { - panic(fmt.Sprintf("Invalid email format: %s", email)) - } else { - // Currently only a single issuer can be set for all the maintainers. - key := tuf.FulcioVerificationKey(strings.TrimSpace(email), o.Issuer) - publicKeys = append(publicKeys, key) - } - } - - // Create a new root. - root := tuf.NewRoot() - - // Add the maintainer identities to the root's trusted keys. - for _, key := range publicKeys { - root.AddKey(key) - } - - // Set root keys, threshold, and namespace. - role, ok := root.Roles["root"] - if !ok { - role = &tuf.Role{KeyIDs: []string{}, Threshold: 1} - } - role.AddKeysWithThreshold(publicKeys, o.Threshold) - root.Roles["root"] = role - root.Namespace = o.ImageRef - - if o.Expires > 0 { - root.Expires = time.Now().AddDate(0, 0, o.Expires).UTC().Round(time.Second) - } - - policy, err := root.Marshal() - if err != nil { - return err - } - policyFile, err := policy.JSONMarshal("", "\t") - if err != nil { - return err - } - - var outfile string - if o.OutFile != "" { - outfile = o.OutFile - err = os.WriteFile(o.OutFile, policyFile, 0600) - if err != nil { - return fmt.Errorf("error writing to %s: %w", outfile, err) - } - } else { - tempFile, err := os.CreateTemp("", "root") - if err != nil { - return err - } - outfile = tempFile.Name() - defer os.Remove(tempFile.Name()) - } - - files := []cremote.File{ - cremote.FileFromFlag(outfile), - } - - return upload.BlobCmd(cmd.Context(), o.Registry, files, "", rootPath(o.ImageRef)) - }, - } - - o.AddFlags(cmd) - - return cmd -} - -func signPolicy() *cobra.Command { - o := &options.PolicySignOptions{} - - cmd := &cobra.Command{ - Use: "sign", - 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 ro.Timeout != 0 { - var cancelFn context.CancelFunc - ctx, cancelFn = context.WithTimeout(ctx, ro.Timeout) - defer cancelFn() - } - - // Get Fulcio signer - oidcClientSecret, err := o.OIDC.ClientSecret() - if err != nil { - return err - } - sv, err := sign.SignerFromKeyOpts(ctx, "", "", options.KeyOpts{ - FulcioURL: o.Fulcio.URL, - IDToken: o.Fulcio.IdentityToken, - InsecureSkipFulcioVerify: o.Fulcio.InsecureSkipFulcioVerify, - RekorURL: o.Rekor.URL, - OIDCIssuer: o.OIDC.Issuer, - OIDCClientID: o.OIDC.ClientID, - OIDCClientSecret: oidcClientSecret, - OIDCRedirectURL: o.OIDC.RedirectURL, - }) - if err != nil { - return err - } - defer sv.Close() - - certs, err := cryptoutils.LoadCertificatesFromPEM(bytes.NewReader(sv.Cert)) - if err != nil { - return err - } - if len(certs) == 0 || certs[0].EmailAddresses == nil { - return errors.New("error decoding certificate") - } - signerEmail := sigs.CertSubject(certs[0]) - signerIssuer := sigs.CertIssuerExtension(certs[0]) - - // Retrieve root.json from registry. - imgName := rootPath(o.ImageRef) - ref, err := name.ParseReference(imgName) - if err != nil { - return err - } - opts := []remote.Option{ - remote.WithAuthFromKeychain(authn.DefaultKeychain), - remote.WithContext(ctx), - } - - img, err := remote.Image(ref, opts...) - if err != nil { - return err - } - dgst, err := img.Digest() - if err != nil { - return err - } - - result := &bytes.Buffer{} - if err := sget.New(imgName+"@"+dgst.String(), "", result).Do(ctx); err != nil { - return fmt.Errorf("error getting result: %w", err) - } - b, err := io.ReadAll(result) - if err != nil { - return fmt.Errorf("error reading bytes from root.json: %w", err) - } - - // Unmarshal policy and verify that Fulcio signer email is in the trusted - signed := &tuf.Signed{} - if err := json.Unmarshal(b, signed); err != nil { - return fmt.Errorf("unmarshalling signed root policy: %w", err) - } - - // Create and add signature - key := tuf.FulcioVerificationKey(signerEmail, signerIssuer) - sig, err := sv.SignMessage(bytes.NewReader(signed.Signed), signatureoptions.WithContext(ctx)) - if err != nil { - return fmt.Errorf("error occurred while during artifact signing): %w", err) - } - signature := tuf.Signature{ - Signature: base64.StdEncoding.EncodeToString(sig), - Cert: base64.StdEncoding.EncodeToString(sv.Cert), - } - if err := signed.AddOrUpdateSignature(key, signature); err != nil { - return err - } - - // Upload to rekor - if options.EnableExperimental() { - // TODO: Refactor with sign.go - rekorBytes := sv.Cert - rekorClient, err := rekor.NewClient(o.Rekor.URL) - if err != nil { - return err - } - entry, err := cosign.TLogUpload(ctx, rekorClient, sig, signed.Signed, rekorBytes) - if err != nil { - return err - } - fmt.Fprintln(os.Stderr, "tlog entry created with index:", *entry.LogIndex) - } - - // Push updated root.json to the registry - policyFile, err := signed.JSONMarshal("", "\t") - if err != nil { - return err - } - - var outfile string - if o.OutFile != "" { - outfile = o.OutFile - err = os.WriteFile(o.OutFile, policyFile, 0600) - if err != nil { - return fmt.Errorf("error writing to %s: %w", outfile, err) - } - } else { - tempFile, err := os.CreateTemp("", "root") - if err != nil { - return err - } - outfile = tempFile.Name() - defer os.Remove(tempFile.Name()) - } - - files := []cremote.File{ - cremote.FileFromFlag(outfile), - } - - return upload.BlobCmd(ctx, o.Registry, files, "", rootPath(o.ImageRef)) - }, - } - - o.AddFlags(cmd) - - return cmd -} diff --git a/cmd/cosign/cli/policy_init_test.go b/cmd/cosign/cli/policy_init_test.go deleted file mode 100644 index 1d0fbea85..000000000 --- a/cmd/cosign/cli/policy_init_test.go +++ /dev/null @@ -1,33 +0,0 @@ -// -// Copyright 2021 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 cli - -import ( - "testing" -) - -// Tests correctly formatted emails do not fail validEmail call -// Tests incorrectly formatted emails do not pass validEmail call -func TestEmailValid(t *testing.T) { - goodEmail := "foo@foo.com" - strongBadEmail := "foofoocom" - - if !validEmail(goodEmail) { - t.Errorf("correct email %s, failed valid check", goodEmail) - } else if validEmail(strongBadEmail) { - t.Errorf("bad email %s, passed valid check", strongBadEmail) - } -} diff --git a/cmd/cosign/cli/public_key.go b/cmd/cosign/cli/public_key.go deleted file mode 100644 index 261051bc1..000000000 --- a/cmd/cosign/cli/public_key.go +++ /dev/null @@ -1,92 +0,0 @@ -// -// Copyright 2021 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 cli - -import ( - "os" - - "github.com/spf13/cobra" - - "github.com/sigstore/policy-controller/cmd/cosign/cli/generate" - "github.com/sigstore/policy-controller/cmd/cosign/cli/options" - "github.com/sigstore/policy-controller/cmd/cosign/cli/publickey" -) - -func PublicKey() *cobra.Command { - o := &options.PublicKeyOptions{} - - cmd := &cobra.Command{ - Use: "public-key", - Short: "Gets a public key from the key-pair.", - Long: "Gets a public key from the key-pair and\nwrites to a specified file. By default, it will write to standard out.", - Example: ` - # extract public key from private key to a specified out file. - cosign public-key --key --outfile - - # extract public key from URL. - cosign public-key --key https://host.for/ --outfile - - # extract public key from Azure Key Vault - cosign public-key --key azurekms://[VAULT_NAME][VAULT_URI]/[KEY] - - # extract public key from AWS KMS - cosign public-key --key awskms://[ENDPOINT]/[ID/ALIAS/ARN] - - # extract public key from Google Cloud KMS - cosign public-key --key gcpkms://projects/[PROJECT]/locations/global/keyRings/[KEYRING]/cryptoKeys/[KEY] - - # extract public key from Hashicorp Vault KMS - cosign public-key --key hashivault://[KEY] - - # extract public key from GitLab with project name - cosign verify --key gitlab://[OWNER]/[PROJECT_NAME] - - # extract public key from GitLab with project id - cosign verify --key gitlab://[PROJECT_ID] `, - PreRunE: func(cmd *cobra.Command, args []string) error { - if !options.OneOf(o.Key, o.SecurityKey.Use) { - return &options.KeyParseError{} - } - return nil - }, - RunE: func(cmd *cobra.Command, args []string) error { - writer := publickey.NamedWriter{Name: "", Writer: nil} - var f *os.File - // Open output file for public key if specified. - if o.OutFile != "" { - writer.Name = o.OutFile - var err error - f, err = os.OpenFile(o.OutFile, os.O_WRONLY|os.O_CREATE, 0600) - if err != nil { - return err - } - writer.Writer = f - defer f.Close() - } else { - writer.Writer = os.Stdout - } - pk := publickey.Pkopts{ - KeyRef: o.Key, - Sk: o.SecurityKey.Use, - Slot: o.SecurityKey.Slot, - } - return publickey.GetPublicKey(cmd.Context(), pk, writer, generate.GetPass) - }, - } - - o.AddFlags(cmd) - return cmd -} diff --git a/cmd/cosign/cli/rekor/rekor.go b/cmd/cosign/cli/rekor/rekor.go deleted file mode 100644 index eed03fa7a..000000000 --- a/cmd/cosign/cli/rekor/rekor.go +++ /dev/null @@ -1,30 +0,0 @@ -// Copyright 2021 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 ( - rekor "github.com/sigstore/rekor/pkg/client" - "github.com/sigstore/rekor/pkg/generated/client" - - "github.com/sigstore/policy-controller/cmd/cosign/cli/options" -) - -func NewClient(rekorURL string) (*client.Rekor, error) { - rekorClient, err := rekor.GetRekorClient(rekorURL, rekor.WithUserAgent(options.UserAgent())) - if err != nil { - return nil, err - } - return rekorClient, nil -} diff --git a/cmd/cosign/cli/rekor/rekor_test.go b/cmd/cosign/cli/rekor/rekor_test.go deleted file mode 100644 index 398171f6a..000000000 --- a/cmd/cosign/cli/rekor/rekor_test.go +++ /dev/null @@ -1,52 +0,0 @@ -// Copyright 2021 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 ( - "net/http" - "net/http/httptest" - "testing" - - "github.com/sigstore/policy-controller/cmd/cosign/cli/options" -) - -func TestNewClient(t *testing.T) { - t.Parallel() - expectedUserAgent := options.UserAgent() - requestReceived := false - testServer := httptest.NewServer(http.HandlerFunc( - func(w http.ResponseWriter, r *http.Request) { - requestReceived = true - file := []byte{} - - got := r.UserAgent() - if got != expectedUserAgent { - t.Errorf("wanted User-Agent %q, got %q", expectedUserAgent, got) - } - w.WriteHeader(http.StatusOK) - _, _ = w.Write(file) - })) - defer testServer.Close() - - client, err := NewClient(testServer.URL) - if err != nil { - t.Error(err) - } - _, _ = client.Tlog.GetLogInfo(nil) - - if !requestReceived { - t.Fatal("no requests were received") - } -} diff --git a/cmd/cosign/cli/save.go b/cmd/cosign/cli/save.go deleted file mode 100644 index ad9477f0a..000000000 --- a/cmd/cosign/cli/save.go +++ /dev/null @@ -1,76 +0,0 @@ -// -// Copyright 2021 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 cli - -import ( - "context" - "errors" - "fmt" - - "github.com/google/go-containerregistry/pkg/name" - "github.com/sigstore/policy-controller/cmd/cosign/cli/options" - "github.com/sigstore/policy-controller/pkg/oci" - "github.com/sigstore/policy-controller/pkg/oci/layout" - ociremote "github.com/sigstore/policy-controller/pkg/oci/remote" - "github.com/spf13/cobra" -) - -func Save() *cobra.Command { - o := &options.SaveOptions{} - - cmd := &cobra.Command{ - Use: "save", - Short: "Save the container image and associated signatures to disk at the specified directory.", - Long: "Save the container image and associated signatures to disk at the specified directory.", - Example: ` cosign save --dir `, - Args: cobra.ExactArgs(1), - RunE: func(cmd *cobra.Command, args []string) error { - return SaveCmd(cmd.Context(), *o, args[0]) - }, - } - - o.AddFlags(cmd) - return cmd -} - -func SaveCmd(ctx context.Context, opts options.SaveOptions, imageRef string) error { - ref, err := name.ParseReference(imageRef) - if err != nil { - return fmt.Errorf("parsing image name %s: %w", imageRef, err) - } - - se, err := ociremote.SignedEntity(ref) - if err != nil { - return fmt.Errorf("signed entity: %w", err) - } - - if _, ok := se.(oci.SignedImage); ok { - si, err := ociremote.SignedImage(ref) - if err != nil { - return fmt.Errorf("getting signed image: %w", err) - } - return layout.WriteSignedImage(opts.Directory, si) - } - - if _, ok := se.(oci.SignedImageIndex); ok { - sii, err := ociremote.SignedImageIndex(ref) - if err != nil { - return fmt.Errorf("getting signed image index: %w", err) - } - return layout.WriteSignedImageIndex(opts.Directory, sii) - } - return errors.New("unknown signed entity") -} diff --git a/cmd/cosign/cli/sign.go b/cmd/cosign/cli/sign.go deleted file mode 100644 index 1934f8145..000000000 --- a/cmd/cosign/cli/sign.go +++ /dev/null @@ -1,116 +0,0 @@ -// -// Copyright 2021 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 cli - -import ( - "flag" - "fmt" - - "github.com/spf13/cobra" - - "github.com/sigstore/policy-controller/cmd/cosign/cli/generate" - "github.com/sigstore/policy-controller/cmd/cosign/cli/options" - "github.com/sigstore/policy-controller/cmd/cosign/cli/sign" -) - -func Sign() *cobra.Command { - o := &options.SignOptions{} - - cmd := &cobra.Command{ - Use: "sign", - Short: "Sign the supplied container image.", - Long: "Sign the supplied container image.", - Example: ` cosign sign --key | [--payload ] [-a key=value] [--upload=true|false] [-f] [-r] - - # sign a container image with Google sign-in (experimental) - COSIGN_EXPERIMENTAL=1 cosign sign - - # sign a container image with a local key pair file - cosign sign --key cosign.key - - # sign a multi-arch container image AND all referenced, discrete images - cosign sign --key cosign.key --recursive - - # sign a container image and add annotations - cosign sign --key cosign.key -a key1=value1 -a key2=value2 - - # sign a container image with a key stored in an environment variable - cosign sign --key env://[ENV_VAR] - - # sign a container image with a key pair stored in Azure Key Vault - cosign sign --key azurekms://[VAULT_NAME][VAULT_URI]/[KEY] - - # sign a container image with a key pair stored in AWS KMS - cosign sign --key awskms://[ENDPOINT]/[ID/ALIAS/ARN] - - # sign a container image with a key pair stored in Google Cloud KMS - cosign sign --key gcpkms://projects/[PROJECT]/locations/global/keyRings/[KEYRING]/cryptoKeys/[KEY]/versions/[VERSION] - - # sign a container image with a key pair stored in Hashicorp Vault - cosign sign --key hashivault://[KEY] - - # sign a container image with a key pair stored in a Kubernetes secret - cosign sign --key k8s://[NAMESPACE]/[KEY] - - # sign a container image with a key, attaching a certificate and certificate chain - cosign sign --key cosign.key --cert cosign.crt --cert-chain chain.crt - - # sign a container in a registry which does not fully support OCI media types - COSIGN_DOCKER_MEDIA_TYPES=1 cosign sign --key cosign.key legacy-registry.example.com/my/image`, - Args: cobra.MinimumNArgs(1), - RunE: func(cmd *cobra.Command, args []string) error { - switch o.Attachment { - case "sbom", "": - break - default: - return flag.ErrHelp - } - oidcClientSecret, err := o.OIDC.ClientSecret() - if err != nil { - return err - } - ko := options.KeyOpts{ - KeyRef: o.Key, - PassFunc: generate.GetPass, - Sk: o.SecurityKey.Use, - Slot: o.SecurityKey.Slot, - FulcioURL: o.Fulcio.URL, - IDToken: o.Fulcio.IdentityToken, - InsecureSkipFulcioVerify: o.Fulcio.InsecureSkipFulcioVerify, - RekorURL: o.Rekor.URL, - OIDCIssuer: o.OIDC.Issuer, - OIDCClientID: o.OIDC.ClientID, - OIDCClientSecret: oidcClientSecret, - OIDCRedirectURL: o.OIDC.RedirectURL, - OIDCDisableProviders: o.OIDC.DisableAmbientProviders, - } - annotationsMap, err := o.AnnotationsMap() - if err != nil { - return err - } - if err := sign.SignCmd(ro, ko, o.Registry, annotationsMap.Annotations, args, o.Cert, o.CertChain, o.Upload, - o.OutputSignature, o.OutputCertificate, o.PayloadPath, o.Force, o.Recursive, o.Attachment); err != nil { - if o.Attachment == "" { - return fmt.Errorf("signing %v: %w", args, err) - } - return fmt.Errorf("signing attachment %s for image %v: %w", o.Attachment, args, err) - } - return nil - }, - } - o.AddFlags(cmd) - return cmd -} diff --git a/cmd/cosign/cli/sign/sign.go b/cmd/cosign/cli/sign/sign.go deleted file mode 100644 index 37efe093a..000000000 --- a/cmd/cosign/cli/sign/sign.go +++ /dev/null @@ -1,502 +0,0 @@ -// -// Copyright 2021 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 sign - -import ( - "bytes" - "context" - "crypto/x509" - "encoding/pem" - "errors" - "fmt" - "os" - "path/filepath" - "strings" - - "github.com/google/go-containerregistry/pkg/name" - v1 "github.com/google/go-containerregistry/pkg/v1" - "github.com/google/go-containerregistry/pkg/v1/remote" - - "github.com/sigstore/policy-controller/cmd/cosign/cli/fulcio" - "github.com/sigstore/policy-controller/cmd/cosign/cli/fulcio/fulcioverifier" - "github.com/sigstore/policy-controller/cmd/cosign/cli/fulcio/fulcioverifier/ctl" - "github.com/sigstore/policy-controller/cmd/cosign/cli/options" - "github.com/sigstore/policy-controller/cmd/cosign/cli/rekor" - icos "github.com/sigstore/policy-controller/internal/pkg/cosign" - ifulcio "github.com/sigstore/policy-controller/internal/pkg/cosign/fulcio" - ipayload "github.com/sigstore/policy-controller/internal/pkg/cosign/payload" - irekor "github.com/sigstore/policy-controller/internal/pkg/cosign/rekor" - "github.com/sigstore/policy-controller/pkg/cosign" - "github.com/sigstore/policy-controller/pkg/cosign/pivkey" - "github.com/sigstore/policy-controller/pkg/cosign/pkcs11key" - cremote "github.com/sigstore/policy-controller/pkg/cosign/remote" - "github.com/sigstore/policy-controller/pkg/oci" - "github.com/sigstore/policy-controller/pkg/oci/mutate" - ociremote "github.com/sigstore/policy-controller/pkg/oci/remote" - "github.com/sigstore/policy-controller/pkg/oci/walk" - sigs "github.com/sigstore/policy-controller/pkg/signature" - "github.com/sigstore/sigstore/pkg/cryptoutils" - "github.com/sigstore/sigstore/pkg/signature" - signatureoptions "github.com/sigstore/sigstore/pkg/signature/options" - sigPayload "github.com/sigstore/sigstore/pkg/signature/payload" - - // Loads OIDC providers - _ "github.com/sigstore/policy-controller/pkg/providers/all" -) - -func ShouldUploadToTlog(ctx context.Context, ref name.Reference, force bool, url string) bool { - // Check whether experimental is on! - if !options.EnableExperimental() { - return false - } - // We are forcing publishing to the Tlog. - if force { - return true - } - - // Check if the image is public (no auth in Get) - if _, err := remote.Get(ref, remote.WithContext(ctx)); err != nil { - fmt.Fprintf(os.Stderr, "%q appears to be a private repository, please confirm uploading to the transparency log at %q [Y/N]: ", ref.Context().String(), url) - - var tlogConfirmResponse string - if _, err := fmt.Scanln(&tlogConfirmResponse); err != nil { - fmt.Fprintf(os.Stderr, "\nWARNING: skipping transparency log upload (use --force to upload from scripts): %v\n", err) - return false - } - if strings.ToUpper(tlogConfirmResponse) != "Y" { - fmt.Fprintln(os.Stderr, "not uploading to transparency log") - return false - } - } - return true -} - -func GetAttachedImageRef(ref name.Reference, attachment string, opts ...ociremote.Option) (name.Reference, error) { - if attachment == "" { - return ref, nil - } - if attachment == "sbom" { - return ociremote.SBOMTag(ref, opts...) - } - return nil, fmt.Errorf("unknown attachment type %s", attachment) -} - -// nolint -func SignCmd(ro *options.RootOptions, ko options.KeyOpts, regOpts options.RegistryOptions, annotations map[string]interface{}, - imgs []string, certPath string, certChainPath string, upload bool, outputSignature, outputCertificate string, - payloadPath string, force bool, recursive bool, attachment string) error { - if options.EnableExperimental() { - if options.NOf(ko.KeyRef, ko.Sk) > 1 { - return &options.KeyParseError{} - } - } else { - if !options.OneOf(ko.KeyRef, ko.Sk) { - return &options.KeyParseError{} - } - } - - ctx, cancel := context.WithTimeout(context.Background(), ro.Timeout) - defer cancel() - - sv, err := SignerFromKeyOpts(ctx, certPath, certChainPath, ko) - if err != nil { - return fmt.Errorf("getting signer: %w", err) - } - defer sv.Close() - dd := cremote.NewDupeDetector(sv) - - var staticPayload []byte - if payloadPath != "" { - fmt.Fprintln(os.Stderr, "Using payload from:", payloadPath) - staticPayload, err = os.ReadFile(filepath.Clean(payloadPath)) - if err != nil { - return fmt.Errorf("payload from file: %w", err) - } - } - - // Set up an ErrDone consideration to return along "success" paths - var ErrDone error - if !recursive { - ErrDone = mutate.ErrSkipChildren - } - - for _, inputImg := range imgs { - ref, err := name.ParseReference(inputImg) - if err != nil { - return fmt.Errorf("parsing reference: %w", err) - } - opts, err := regOpts.ClientOpts(ctx) - if err != nil { - return fmt.Errorf("constructing client options: %w", err) - } - ref, err = GetAttachedImageRef(ref, attachment, opts...) - if err != nil { - return fmt.Errorf("unable to resolve attachment %s for image %s", attachment, inputImg) - } - - if digest, ok := ref.(name.Digest); ok && !recursive { - se, err := ociremote.SignedEntity(ref, opts...) - if err != nil { - return fmt.Errorf("accessing image: %w", err) - } - err = signDigest(ctx, digest, staticPayload, ko, regOpts, annotations, upload, outputSignature, outputCertificate, force, recursive, dd, sv, se) - if err != nil { - return fmt.Errorf("signing digest: %w", err) - } - continue - } - - se, err := ociremote.SignedEntity(ref, opts...) - if err != nil { - return fmt.Errorf("accessing entity: %w", err) - } - - if err := walk.SignedEntity(ctx, se, func(ctx context.Context, se oci.SignedEntity) error { - // Get the digest for this entity in our walk. - d, err := se.(interface{ Digest() (v1.Hash, error) }).Digest() - if err != nil { - return fmt.Errorf("computing digest: %w", err) - } - digest := ref.Context().Digest(d.String()) - - err = signDigest(ctx, digest, staticPayload, ko, regOpts, annotations, upload, outputSignature, outputCertificate, force, recursive, dd, sv, se) - if err != nil { - return fmt.Errorf("signing digest: %w", err) - } - return ErrDone - }); err != nil { - return fmt.Errorf("recursively signing: %w", err) - } - } - - return nil -} - -func signDigest(ctx context.Context, digest name.Digest, payload []byte, ko options.KeyOpts, - regOpts options.RegistryOptions, annotations map[string]interface{}, upload bool, outputSignature, outputCertificate string, force bool, recursive bool, - dd mutate.DupeDetector, sv *SignerVerifier, se oci.SignedEntity) error { - var err error - // The payload can be passed to skip generation. - if len(payload) == 0 { - payload, err = (&sigPayload.Cosign{ - Image: digest, - Annotations: annotations, - }).MarshalJSON() - if err != nil { - return fmt.Errorf("payload: %w", err) - } - } - - var s icos.Signer - s = ipayload.NewSigner(sv) - if sv.Cert != nil { - s = ifulcio.NewSigner(s, sv.Cert, sv.Chain) - } - if ShouldUploadToTlog(ctx, digest, force, ko.RekorURL) { - rClient, err := rekor.NewClient(ko.RekorURL) - if err != nil { - return err - } - s = irekor.NewSigner(s, rClient) - } - - ociSig, _, err := s.Sign(ctx, bytes.NewReader(payload)) - if err != nil { - return err - } - - b64sig, err := ociSig.Base64Signature() - if err != nil { - return err - } - - if outputSignature != "" { - // Add digest to suffix to differentiate each image during recursive signing - if recursive { - outputSignature = fmt.Sprintf("%s-%s", outputSignature, strings.Replace(digest.DigestStr(), ":", "-", 1)) - } - if err := os.WriteFile(outputSignature, []byte(b64sig), 0600); err != nil { - return fmt.Errorf("create signature file: %w", err) - } - } - - if outputCertificate != "" { - rekorBytes, err := sv.Bytes(ctx) - if err != nil { - return fmt.Errorf("create certificate file: %w", err) - } - - if err := os.WriteFile(outputCertificate, rekorBytes, 0600); err != nil { - return fmt.Errorf("create certificate file: %w", err) - } - // TODO: maybe accept a --b64 flag as well? - fmt.Printf("Certificate wrote in the file %s\n", outputCertificate) - } - - if !upload { - return nil - } - - // Attach the signature to the entity. - newSE, err := mutate.AttachSignatureToEntity(se, ociSig, mutate.WithDupeDetector(dd)) - if err != nil { - return err - } - - // Publish the signatures associated with this entity - walkOpts, err := regOpts.ClientOpts(ctx) - if err != nil { - return fmt.Errorf("constructing client options: %w", err) - } - - // Check if we are overriding the signatures repository location - repo, _ := ociremote.GetEnvTargetRepository() - if repo.RepositoryStr() == "" { - fmt.Fprintln(os.Stderr, "Pushing signature to:", digest.Repository) - } else { - fmt.Fprintln(os.Stderr, "Pushing signature to:", repo.RepositoryStr()) - } - - // Publish the signatures associated with this entity - if err := ociremote.WriteSignatures(digest.Repository, newSE, walkOpts...); err != nil { - return err - } - - return nil -} - -func signerFromSecurityKey(keySlot string) (*SignerVerifier, error) { - sk, err := pivkey.GetKeyWithSlot(keySlot) - if err != nil { - return nil, err - } - sv, err := sk.SignerVerifier() - if err != nil { - sk.Close() - return nil, err - } - - // Handle the -cert flag. - // With PIV, we assume the certificate is in the same slot on the PIV - // token as the private key. If it's not there, show a warning to the - // user. - certFromPIV, err := sk.Certificate() - var pemBytes []byte - if err != nil { - fmt.Fprintln(os.Stderr, "warning: no x509 certificate retrieved from the PIV token") - } else { - pemBytes, err = cryptoutils.MarshalCertificateToPEM(certFromPIV) - if err != nil { - sk.Close() - return nil, err - } - } - - return &SignerVerifier{ - Cert: pemBytes, - SignerVerifier: sv, - close: sk.Close, - }, nil -} - -func signerFromKeyRef(ctx context.Context, certPath, certChainPath, keyRef string, passFunc cosign.PassFunc) (*SignerVerifier, error) { - k, err := sigs.SignerVerifierFromKeyRef(ctx, keyRef, passFunc) - if err != nil { - return nil, fmt.Errorf("reading key: %w", err) - } - certSigner := &SignerVerifier{ - SignerVerifier: k, - } - - var leafCert *x509.Certificate - - // Attempt to extract certificate from PKCS11 token - // With PKCS11, we assume the certificate is in the same slot on the PKCS11 - // token as the private key. If it's not there, show a warning to the - // user. - if pkcs11Key, ok := k.(*pkcs11key.Key); ok { - certFromPKCS11, _ := pkcs11Key.Certificate() - certSigner.close = pkcs11Key.Close - - if certFromPKCS11 == nil { - fmt.Fprintln(os.Stderr, "warning: no x509 certificate retrieved from the PKCS11 token") - } else { - pemBytes, err := cryptoutils.MarshalCertificateToPEM(certFromPKCS11) - if err != nil { - pkcs11Key.Close() - return nil, err - } - // Check that the provided public key and certificate key match - pubKey, err := k.PublicKey() - if err != nil { - pkcs11Key.Close() - return nil, err - } - if cryptoutils.EqualKeys(pubKey, certFromPKCS11.PublicKey) != nil { - pkcs11Key.Close() - return nil, errors.New("pkcs11 key and certificate do not match") - } - leafCert = certFromPKCS11 - certSigner.Cert = pemBytes - } - } - - // Handle --cert flag - if certPath != "" { - // Allow both DER and PEM encoding - certBytes, err := os.ReadFile(certPath) - if err != nil { - return nil, fmt.Errorf("read certificate: %w", err) - } - // Handle PEM - if bytes.HasPrefix(certBytes, []byte("-----")) { - decoded, _ := pem.Decode(certBytes) - if decoded.Type != "CERTIFICATE" { - return nil, fmt.Errorf("supplied PEM file is not a certificate: %s", certPath) - } - certBytes = decoded.Bytes - } - parsedCert, err := x509.ParseCertificate(certBytes) - if err != nil { - return nil, fmt.Errorf("parse x509 certificate: %w", err) - } - pk, err := k.PublicKey() - if err != nil { - return nil, fmt.Errorf("get public key: %w", err) - } - if cryptoutils.EqualKeys(pk, parsedCert.PublicKey) != nil { - return nil, errors.New("public key in certificate does not match the provided public key") - } - pemBytes, err := cryptoutils.MarshalCertificateToPEM(parsedCert) - if err != nil { - return nil, fmt.Errorf("marshaling certificate to PEM: %w", err) - } - if certSigner.Cert != nil { - fmt.Fprintln(os.Stderr, "warning: overriding x509 certificate retrieved from the PKCS11 token") - } - leafCert = parsedCert - certSigner.Cert = pemBytes - } - - if certChainPath == "" { - return certSigner, nil - } else if certSigner.Cert == nil { - return nil, errors.New("no leaf certificate found or provided while specifying chain") - } - - // Handle --cert-chain flag - // Accept only PEM encoded certificate chain - certChainBytes, err := os.ReadFile(certChainPath) - if err != nil { - return nil, fmt.Errorf("reading certificate chain from path: %w", err) - } - certChain, err := cryptoutils.LoadCertificatesFromPEM(bytes.NewReader(certChainBytes)) - if err != nil { - return nil, fmt.Errorf("loading certificate chain: %w", err) - } - if len(certChain) == 0 { - return nil, errors.New("no certificates in certificate chain") - } - // Verify certificate chain is valid - rootPool := x509.NewCertPool() - rootPool.AddCert(certChain[len(certChain)-1]) - subPool := x509.NewCertPool() - for _, c := range certChain[:len(certChain)-1] { - subPool.AddCert(c) - } - if _, err := cosign.TrustedCert(leafCert, rootPool, subPool); err != nil { - return nil, fmt.Errorf("unable to validate certificate chain: %w", err) - } - // Verify SCT if present in the leaf certificate. - contains, err := ctl.ContainsSCT(leafCert.Raw) - if err != nil { - return nil, err - } - if contains { - var chain []*x509.Certificate - chain = append(chain, leafCert) - chain = append(chain, certChain...) - if err := ctl.VerifyEmbeddedSCT(context.Background(), chain); err != nil { - return nil, err - } - } - certSigner.Chain = certChainBytes - - return certSigner, nil -} - -func keylessSigner(ctx context.Context, ko options.KeyOpts) (*SignerVerifier, error) { - var ( - k *fulcio.Signer - err error - ) - - if ko.InsecureSkipFulcioVerify { - if k, err = fulcio.NewSigner(ctx, ko); err != nil { - return nil, fmt.Errorf("getting key from Fulcio: %w", err) - } - } else { - if k, err = fulcioverifier.NewSigner(ctx, ko); err != nil { - return nil, fmt.Errorf("getting key from Fulcio: %w", err) - } - } - - return &SignerVerifier{ - Cert: k.Cert, - Chain: k.Chain, - SignerVerifier: k, - }, nil -} - -func SignerFromKeyOpts(ctx context.Context, certPath string, certChainPath string, ko options.KeyOpts) (*SignerVerifier, error) { - if ko.Sk { - return signerFromSecurityKey(ko.Slot) - } - - if ko.KeyRef != "" { - return signerFromKeyRef(ctx, certPath, certChainPath, ko.KeyRef, ko.PassFunc) - } - - // Default Keyless! - fmt.Fprintln(os.Stderr, "Generating ephemeral keys...") - return keylessSigner(ctx, ko) -} - -type SignerVerifier struct { - Cert []byte - Chain []byte - signature.SignerVerifier - close func() -} - -func (c *SignerVerifier) Close() { - if c.close != nil { - c.close() - } -} - -func (c *SignerVerifier) Bytes(ctx context.Context) ([]byte, error) { - if c.Cert != nil { - fmt.Fprintf(os.Stderr, "using ephemeral certificate:\n%s\n", string(c.Cert)) - return c.Cert, nil - } - - pemBytes, err := sigs.PublicKeyPem(c, signatureoptions.WithContext(ctx)) - if err != nil { - return nil, err - } - return pemBytes, nil -} diff --git a/cmd/cosign/cli/sign/sign_blob.go b/cmd/cosign/cli/sign/sign_blob.go deleted file mode 100644 index 8d71c172e..000000000 --- a/cmd/cosign/cli/sign/sign_blob.go +++ /dev/null @@ -1,129 +0,0 @@ -// -// Copyright 2021 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 sign - -import ( - "bytes" - "context" - "encoding/base64" - "encoding/json" - "fmt" - "io" - "os" - "path/filepath" - - cbundle "github.com/sigstore/policy-controller/pkg/cosign/bundle" - - "github.com/sigstore/policy-controller/cmd/cosign/cli/options" - "github.com/sigstore/policy-controller/cmd/cosign/cli/rekor" - "github.com/sigstore/policy-controller/pkg/cosign" - signatureoptions "github.com/sigstore/sigstore/pkg/signature/options" -) - -// nolint -func SignBlobCmd(ro *options.RootOptions, ko options.KeyOpts, regOpts options.RegistryOptions, payloadPath string, b64 bool, outputSignature string, outputCertificate string) ([]byte, error) { - var payload []byte - var err error - var rekorBytes []byte - - if payloadPath == "-" { - payload, err = io.ReadAll(os.Stdin) - } else { - fmt.Fprintln(os.Stderr, "Using payload from:", payloadPath) - payload, err = os.ReadFile(filepath.Clean(payloadPath)) - } - if err != nil { - return nil, err - } - - ctx, cancel := context.WithTimeout(context.Background(), ro.Timeout) - defer cancel() - - sv, err := SignerFromKeyOpts(ctx, "", "", ko) - if err != nil { - return nil, err - } - defer sv.Close() - - sig, err := sv.SignMessage(bytes.NewReader(payload), signatureoptions.WithContext(ctx)) - if err != nil { - return nil, fmt.Errorf("signing blob: %w", err) - } - - signedPayload := cosign.LocalSignedPayload{} - - if options.EnableExperimental() { - rekorBytes, err = sv.Bytes(ctx) - if err != nil { - return nil, err - } - rekorClient, err := rekor.NewClient(ko.RekorURL) - if err != nil { - return nil, err - } - entry, err := cosign.TLogUpload(ctx, rekorClient, sig, payload, rekorBytes) - if err != nil { - return nil, err - } - fmt.Fprintln(os.Stderr, "tlog entry created with index:", *entry.LogIndex) - signedPayload.Bundle = cbundle.EntryToBundle(entry) - } - - // if bundle is specified, just do that and ignore the rest - if ko.BundlePath != "" { - signedPayload.Base64Signature = base64.StdEncoding.EncodeToString(sig) - signedPayload.Cert = base64.StdEncoding.EncodeToString(rekorBytes) - - contents, err := json.Marshal(signedPayload) - if err != nil { - return nil, err - } - return []byte(signedPayload.Base64Signature), os.WriteFile(ko.BundlePath, contents, 0600) - } - - if outputSignature != "" { - var bts = sig - if b64 { - bts = []byte(base64.StdEncoding.EncodeToString(sig)) - } - if err := os.WriteFile(outputSignature, bts, 0600); err != nil { - return nil, fmt.Errorf("create signature file: %w", err) - } - - fmt.Printf("Signature wrote in the file %s\n", outputSignature) - } else { - if b64 { - sig = []byte(base64.StdEncoding.EncodeToString(sig)) - fmt.Println(string(sig)) - } else if _, err := os.Stdout.Write(sig); err != nil { - // No newline if using the raw signature - return nil, err - } - } - - if outputCertificate != "" && len(rekorBytes) > 0 { - bts := rekorBytes - if b64 { - bts = []byte(base64.StdEncoding.EncodeToString(rekorBytes)) - } - if err := os.WriteFile(outputCertificate, bts, 0600); err != nil { - return nil, fmt.Errorf("create certificate file: %w", err) - } - fmt.Printf("Certificate wrote in the file %s\n", outputCertificate) - } - - return sig, nil -} diff --git a/cmd/cosign/cli/sign/sign_test.go b/cmd/cosign/cli/sign/sign_test.go deleted file mode 100644 index 41e043106..000000000 --- a/cmd/cosign/cli/sign/sign_test.go +++ /dev/null @@ -1,206 +0,0 @@ -// -// Copyright 2021 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 sign - -import ( - "context" - "crypto/ecdsa" - "crypto/x509" - "encoding/pem" - "errors" - "os" - "reflect" - "strings" - "testing" - - "github.com/sigstore/policy-controller/cmd/cosign/cli/generate" - "github.com/sigstore/policy-controller/cmd/cosign/cli/options" - "github.com/sigstore/policy-controller/pkg/cosign" - "github.com/sigstore/policy-controller/test" - "github.com/sigstore/sigstore/pkg/cryptoutils" - "github.com/theupdateframework/go-tuf/encrypted" -) - -func pass(s string) cosign.PassFunc { - return func(_ bool) ([]byte, error) { - return []byte(s), nil - } -} - -func generateCertificateFiles(t *testing.T, tmpDir string, pf cosign.PassFunc) (privFile, certFile, chainFile string, privKey *ecdsa.PrivateKey, cert *x509.Certificate, chain []*x509.Certificate) { - t.Helper() - - rootCert, rootKey, _ := test.GenerateRootCa() - subCert, subKey, _ := test.GenerateSubordinateCa(rootCert, rootKey) - leafCert, privKey, _ := test.GenerateLeafCert("subject", "oidc-issuer", subCert, subKey) - pemRoot := pem.EncodeToMemory(&pem.Block{Type: "CERTIFICATE", Bytes: rootCert.Raw}) - pemSub := pem.EncodeToMemory(&pem.Block{Type: "CERTIFICATE", Bytes: subCert.Raw}) - pemLeaf := pem.EncodeToMemory(&pem.Block{Type: "CERTIFICATE", Bytes: leafCert.Raw}) - - x509Encoded, err := x509.MarshalPKCS8PrivateKey(privKey) - if err != nil { - t.Fatalf("failed to encode private key: %v", err) - } - password := []byte{} - if pf != nil { - password, err = pf(true) - if err != nil { - t.Fatalf("failed to read password: %v", err) - } - } - - encBytes, err := encrypted.Encrypt(x509Encoded, password) - if err != nil { - t.Fatalf("failed to encrypt key: %v", err) - } - - // store in PEM format - privBytes := pem.EncodeToMemory(&pem.Block{ - Bytes: encBytes, - Type: cosign.CosignPrivateKeyPemType, - }) - - tmpPrivFile, err := os.CreateTemp(tmpDir, "cosign_test_*.key") - if err != nil { - t.Fatalf("failed to create temp key file: %v", err) - } - defer tmpPrivFile.Close() - if _, err := tmpPrivFile.Write(privBytes); err != nil { - t.Fatalf("failed to write key file: %v", err) - } - - tmpCertFile, err := os.CreateTemp(tmpDir, "cosign.crt") - if err != nil { - t.Fatalf("failed to create temp certificate file: %v", err) - } - defer tmpCertFile.Close() - if _, err := tmpCertFile.Write(pemLeaf); err != nil { - t.Fatalf("failed to write certificate file: %v", err) - } - - tmpChainFile, err := os.CreateTemp(tmpDir, "cosign_chain.crt") - if err != nil { - t.Fatalf("failed to create temp chain file: %v", err) - } - defer tmpChainFile.Close() - pemChain := pemSub - pemChain = append(pemChain, pemRoot...) - if _, err := tmpChainFile.Write(pemChain); err != nil { - t.Fatalf("failed to write chain file: %v", err) - } - - return tmpPrivFile.Name(), tmpCertFile.Name(), tmpChainFile.Name(), privKey, leafCert, []*x509.Certificate{subCert, rootCert} -} - -// TestSignCmdLocalKeyAndSk verifies the SignCmd returns an error -// if both a local key path and a sk are specified -func TestSignCmdLocalKeyAndSk(t *testing.T) { - ro := &options.RootOptions{Timeout: options.DefaultTimeout} - - for _, ko := range []options.KeyOpts{ - // local and sk keys - { - KeyRef: "testLocalPath", - PassFunc: generate.GetPass, - Sk: true, - }, - } { - err := SignCmd(ro, ko, options.RegistryOptions{}, nil, nil, "", "", false, "", "", "", false, false, "") - if (errors.Is(err, &options.KeyParseError{}) == false) { - t.Fatal("expected KeyParseError") - } - } -} - -func Test_signerFromKeyRefSuccess(t *testing.T) { - tmpDir := t.TempDir() - ctx := context.Background() - keyFile, certFile, chainFile, privKey, cert, chain := generateCertificateFiles(t, tmpDir, pass("foo")) - - signer, err := signerFromKeyRef(ctx, certFile, chainFile, keyFile, pass("foo")) - if err != nil { - t.Fatalf("unexpected error generating signer: %v", err) - } - // Expect public key matches - pubKey, err := signer.SignerVerifier.PublicKey() - if err != nil { - t.Fatalf("unexpected error fetching pubkey: %v", err) - } - if !privKey.Public().(*ecdsa.PublicKey).Equal(pubKey) { - t.Fatalf("public keys must be equal") - } - // Expect certificate matches - expectedPemBytes, err := cryptoutils.MarshalCertificateToPEM(cert) - if err != nil { - t.Fatalf("unexpected error marshalling certificate: %v", err) - } - if !reflect.DeepEqual(signer.Cert, expectedPemBytes) { - t.Fatalf("certificates must match") - } - // Expect certificate chain matches - expectedPemBytesChain, err := cryptoutils.MarshalCertificatesToPEM(chain) - if err != nil { - t.Fatalf("unexpected error marshalling certificate chain: %v", err) - } - if !reflect.DeepEqual(signer.Chain, expectedPemBytesChain) { - t.Fatalf("certificate chains must match") - } -} - -func Test_signerFromKeyRefFailure(t *testing.T) { - tmpDir := t.TempDir() - ctx := context.Background() - keyFile, certFile, _, _, _, _ := generateCertificateFiles(t, tmpDir, pass("foo")) - // Second set of files - tmpDir2 := t.TempDir() - _, certFile2, chainFile2, _, _, _ := generateCertificateFiles(t, tmpDir2, pass("bar")) - - // Public keys don't match - _, err := signerFromKeyRef(ctx, certFile2, chainFile2, keyFile, pass("foo")) - if err == nil || err.Error() != "public key in certificate does not match the provided public key" { - t.Fatalf("expected mismatched keys error, got %v", err) - } - // Certificate chain cannot be verified - _, err = signerFromKeyRef(ctx, certFile, chainFile2, keyFile, pass("foo")) - if err == nil || !strings.Contains(err.Error(), "unable to validate certificate chain") { - t.Fatalf("expected chain verification error, got %v", err) - } - // Certificate chain specified without certificate - _, err = signerFromKeyRef(ctx, "", chainFile2, keyFile, pass("foo")) - if err == nil || !strings.Contains(err.Error(), "no leaf certificate found or provided while specifying chain") { - t.Fatalf("expected no leaf error, got %v", err) - } -} - -func Test_signerFromKeyRefFailureEmptyChainFile(t *testing.T) { - tmpDir := t.TempDir() - ctx := context.Background() - keyFile, certFile, _, _, _, _ := generateCertificateFiles(t, tmpDir, pass("foo")) - - tmpChainFile, err := os.CreateTemp(tmpDir, "cosign_chain_empty.crt") - if err != nil { - t.Fatalf("failed to create temp chain file: %v", err) - } - defer tmpChainFile.Close() - if _, err := tmpChainFile.Write([]byte{}); err != nil { - t.Fatalf("failed to write chain file: %v", err) - } - - _, err = signerFromKeyRef(ctx, certFile, tmpChainFile.Name(), keyFile, pass("foo")) - if err == nil || err.Error() != "no certificates in certificate chain" { - t.Fatalf("expected empty chain error, got %v", err) - } -} diff --git a/cmd/cosign/cli/signblob.go b/cmd/cosign/cli/signblob.go deleted file mode 100644 index 3ed0c35fa..000000000 --- a/cmd/cosign/cli/signblob.go +++ /dev/null @@ -1,102 +0,0 @@ -// -// Copyright 2021 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 cli - -import ( - "fmt" - "os" - - "github.com/sigstore/policy-controller/cmd/cosign/cli/generate" - "github.com/sigstore/policy-controller/cmd/cosign/cli/options" - "github.com/sigstore/policy-controller/cmd/cosign/cli/sign" - "github.com/spf13/cobra" - "github.com/spf13/viper" -) - -func SignBlob() *cobra.Command { - o := &options.SignBlobOptions{} - viper.RegisterAlias("output", "output-signature") - - cmd := &cobra.Command{ - Use: "sign-blob", - Short: "Sign the supplied blob, outputting the base64-encoded signature to stdout.", - Example: ` cosign sign-blob --key | - - # sign a blob with Google sign-in (experimental) - COSIGN_EXPERIMENTAL=1 cosign --timeout 90s sign-blob - - # sign a blob with a local key pair file - cosign sign-blob --key cosign.key - - # sign a blob with a key pair stored in Azure Key Vault - cosign sign-blob --key azurekms://[VAULT_NAME][VAULT_URI]/[KEY] - - # sign a blob with a key pair stored in AWS KMS - cosign sign-blob --key awskms://[ENDPOINT]/[ID/ALIAS/ARN] - - # sign a blob with a key pair stored in Google Cloud KMS - cosign sign-blob --key gcpkms://projects/[PROJECT]/locations/global/keyRings/[KEYRING]/cryptoKeys/[KEY] - - # sign a blob with a key pair stored in Hashicorp Vault - cosign sign-blob --key hashivault://[KEY] `, - Args: cobra.MinimumNArgs(1), - PreRunE: func(cmd *cobra.Command, args []string) error { - // A key file is required unless we're in experimental mode! - if !options.EnableExperimental() { - if !options.OneOf(o.Key, o.SecurityKey.Use) { - return &options.KeyParseError{} - } - } - return nil - }, - RunE: func(cmd *cobra.Command, args []string) error { - oidcClientSecret, err := o.OIDC.ClientSecret() - if err != nil { - return err - } - ko := options.KeyOpts{ - KeyRef: o.Key, - PassFunc: generate.GetPass, - Sk: o.SecurityKey.Use, - Slot: o.SecurityKey.Slot, - FulcioURL: o.Fulcio.URL, - IDToken: o.Fulcio.IdentityToken, - InsecureSkipFulcioVerify: o.Fulcio.InsecureSkipFulcioVerify, - RekorURL: o.Rekor.URL, - OIDCIssuer: o.OIDC.Issuer, - OIDCClientID: o.OIDC.ClientID, - OIDCClientSecret: oidcClientSecret, - OIDCRedirectURL: o.OIDC.RedirectURL, - OIDCDisableProviders: o.OIDC.DisableAmbientProviders, - BundlePath: o.BundlePath, - } - for _, blob := range args { - // TODO: remove when the output flag has been deprecated - if o.Output != "" { - fmt.Fprintln(os.Stderr, "WARNING: the '--output' flag is deprecated and will be removed in the future. Use '--output-signature'") - o.OutputSignature = o.Output - } - if _, err := sign.SignBlobCmd(ro, ko, o.Registry, blob, o.Base64Output, o.OutputSignature, o.OutputCertificate); err != nil { - return fmt.Errorf("signing %s: %w", blob, err) - } - } - return nil - }, - } - - o.AddFlags(cmd) - return cmd -} diff --git a/cmd/cosign/cli/tree.go b/cmd/cosign/cli/tree.go deleted file mode 100644 index 1e00b2683..000000000 --- a/cmd/cosign/cli/tree.go +++ /dev/null @@ -1,155 +0,0 @@ -// -// Copyright 2021 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 cli - -import ( - "context" - "fmt" - "os" - - v1 "github.com/google/go-containerregistry/pkg/v1" - - "github.com/google/go-containerregistry/pkg/name" - "github.com/spf13/cobra" - - "github.com/sigstore/policy-controller/cmd/cosign/cli/options" - ociremote "github.com/sigstore/policy-controller/pkg/oci/remote" -) - -func Tree() *cobra.Command { - c := &options.TreeOptions{} - - cmd := &cobra.Command{ - Use: "tree", - Short: "Display supply chain security related artifacts for an image such as signatures, SBOMs and attestations", - Example: " cosign tree ", - Args: cobra.ExactArgs(1), - RunE: func(cmd *cobra.Command, args []string) error { - return TreeCmd(cmd.Context(), c.Registry, args[0]) - }, - } - - c.AddFlags(cmd) - return cmd -} - -func TreeCmd(ctx context.Context, regOpts options.RegistryOptions, imageRef string) error { - scsaMap := map[name.Tag][]v1.Layer{} - ref, err := name.ParseReference(imageRef) - if err != nil { - return err - } - - remoteOpts, err := regOpts.ClientOpts(ctx) - if err != nil { - return err - } - fmt.Fprintf(os.Stdout, "📦 Supply Chain Security Related artifacts for an image: %s\n", ref.String()) - - simg, err := ociremote.SignedEntity(ref, remoteOpts...) - if err != nil { - return err - } - - attRef, err := ociremote.AttestationTag(ref, remoteOpts...) - if err != nil { - return err - } - - atts, err := simg.Attestations() - if err == nil { - layers, err := atts.Layers() - if err != nil { - return err - } - if len(layers) > 0 { - scsaMap[attRef] = layers - } - } - - sigRef, err := ociremote.SignatureTag(ref, remoteOpts...) - if err != nil { - return err - } - - sigs, err := simg.Signatures() - if err == nil { - layers, err := sigs.Layers() - if err != nil { - return err - } - if len(layers) > 0 { - scsaMap[sigRef] = layers - } - } - - sbomRef, err := ociremote.SBOMTag(ref, remoteOpts...) - if err != nil { - return err - } - - sbombs, err := simg.Attachment(ociremote.SBOMTagSuffix) - if err == nil { - layers, err := sbombs.Layers() - if err != nil { - return err - } - if len(layers) > 0 { - scsaMap[sbomRef] = layers - } - } - - if len(scsaMap) == 0 { - fmt.Fprintf(os.Stdout, "No Supply Chain Security Related Artifacts artifacts found for image %s\n, start creating one with simply running"+ - "$ COSIGN_EXPERIMENTAL=1 cosign sign ", ref.String()) - return nil - } - - for t, k := range scsaMap { - switch t { - case sigRef: - fmt.Fprintf(os.Stdout, "└── 🔐 Signatures for an image tag: %s\n", t.String()) - case sbomRef: - fmt.Fprintf(os.Stdout, "└── 📦 SBOMs for an image tag: %s\n", t.String()) - case attRef: - fmt.Fprintf(os.Stdout, "└── 💾 Attestations for an image tag: %s\n", t.String()) - } - - if err := printLayers(k); err != nil { - return err - } - } - - return nil -} - -func printLayers(layers []v1.Layer) error { - for i, l := range layers { - last := i == len(layers)-1 - var sym string - if last { - sym = " └──" - } else { - sym = " ├──" - } - digest, err := l.Digest() - if err != nil { - return err - } - fmt.Printf("%s 🍒 %s\n", sym, digest) - } - return nil -} diff --git a/cmd/cosign/cli/triangulate.go b/cmd/cosign/cli/triangulate.go deleted file mode 100644 index d1baef989..000000000 --- a/cmd/cosign/cli/triangulate.go +++ /dev/null @@ -1,44 +0,0 @@ -// -// Copyright 2021 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 cli - -import ( - "flag" - - "github.com/spf13/cobra" - - "github.com/sigstore/policy-controller/cmd/cosign/cli/options" - "github.com/sigstore/policy-controller/cmd/cosign/cli/triangulate" -) - -func Triangulate() *cobra.Command { - o := &options.TriangulateOptions{} - - cmd := &cobra.Command{ - Use: "triangulate", - Short: "Outputs the located cosign image reference. This is the location cosign stores the specified artifact type.", - Example: " cosign triangulate ", - RunE: func(cmd *cobra.Command, args []string) error { - if len(args) != 1 { - return flag.ErrHelp - } - return triangulate.MungeCmd(cmd.Context(), o.Registry, args[0], o.Type) - }, - } - - o.AddFlags(cmd) - return cmd -} diff --git a/cmd/cosign/cli/triangulate/triangulate.go b/cmd/cosign/cli/triangulate/triangulate.go deleted file mode 100644 index 3c5b5acef..000000000 --- a/cmd/cosign/cli/triangulate/triangulate.go +++ /dev/null @@ -1,56 +0,0 @@ -// -// Copyright 2021 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 triangulate - -import ( - "context" - "fmt" - - "github.com/google/go-containerregistry/pkg/name" - "github.com/sigstore/policy-controller/cmd/cosign/cli/options" - "github.com/sigstore/policy-controller/pkg/cosign" - ociremote "github.com/sigstore/policy-controller/pkg/oci/remote" -) - -func MungeCmd(ctx context.Context, regOpts options.RegistryOptions, imageRef string, attachmentType string) error { - ref, err := name.ParseReference(imageRef) - if err != nil { - return err - } - - ociremoteOpts, err := regOpts.ClientOpts(ctx) - if err != nil { - return fmt.Errorf("constructing client options: %w", err) - } - - var dstRef name.Tag - switch attachmentType { - case cosign.Signature: - dstRef, err = ociremote.SignatureTag(ref, ociremoteOpts...) - case cosign.SBOM: - dstRef, err = ociremote.SBOMTag(ref, ociremoteOpts...) - case cosign.Attestation: - dstRef, err = ociremote.AttestationTag(ref, ociremoteOpts...) - default: - err = fmt.Errorf("unknown attachment type %s", attachmentType) - } - if err != nil { - return err - } - - fmt.Println(dstRef.Name()) - return nil -} diff --git a/cmd/cosign/cli/upload.go b/cmd/cosign/cli/upload.go deleted file mode 100644 index f72e6425d..000000000 --- a/cmd/cosign/cli/upload.go +++ /dev/null @@ -1,98 +0,0 @@ -// -// Copyright 2021 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 cli - -import ( - "flag" - - "github.com/spf13/cobra" - - "github.com/sigstore/policy-controller/cmd/cosign/cli/options" - "github.com/sigstore/policy-controller/cmd/cosign/cli/upload" -) - -func Upload() *cobra.Command { - cmd := &cobra.Command{ - Use: "upload", - Short: "Provides utilities for uploading artifacts to a registry", - } - - cmd.AddCommand( - uploadBlob(), - uploadWASM(), - ) - - return cmd -} - -func uploadBlob() *cobra.Command { - o := &options.UploadBlobOptions{} - - cmd := &cobra.Command{ - Use: "blob", - Short: "Upload one or more blobs to the supplied container image address.", - Example: ` cosign upload blob -f - - # upload a blob named foo to the location specified by - cosign upload blob -f foo - - # upload a blob named foo to the location specified by , setting the os field to "MYOS". - cosign upload blob -f foo:MYOS - - # upload a blob named foo to the location specified by , setting the os field to "MYOS" and the platform field to "MYPLATFORM". - cosign upload blob -f foo:MYOS/MYPLATFORM - - # upload two blobs named foo-darwin and foo-linux to the location specified by , setting the os fields - cosign upload blob -f foo-darwin:darwin -f foo-linux:linux `, - Args: cobra.ExactArgs(1), - PreRunE: func(cmd *cobra.Command, args []string) error { - if len(o.Files.Files) < 1 { - return flag.ErrHelp - } - return nil - }, - RunE: func(cmd *cobra.Command, args []string) error { - files, err := o.Files.Parse() - if err != nil { - return err - } - - return upload.BlobCmd(cmd.Context(), o.Registry, files, o.ContentType, args[0]) - }, - } - - o.AddFlags(cmd) - - return cmd -} - -func uploadWASM() *cobra.Command { - o := &options.UploadWASMOptions{} - - cmd := &cobra.Command{ - Use: "wasm", - Short: "Upload a wasm module to the supplied container image reference", - Example: " cosign upload wasm -f foo.wasm ", - Args: cobra.ExactArgs(1), - RunE: func(cmd *cobra.Command, args []string) error { - return upload.WasmCmd(cmd.Context(), o.Registry, o.File, args[0]) - }, - } - - o.AddFlags(cmd) - - return cmd -} diff --git a/cmd/cosign/cli/upload/blob.go b/cmd/cosign/cli/upload/blob.go deleted file mode 100644 index 24566f479..000000000 --- a/cmd/cosign/cli/upload/blob.go +++ /dev/null @@ -1,60 +0,0 @@ -// -// Copyright 2021 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 upload - -import ( - "context" - "errors" - "fmt" - "os" - - "github.com/google/go-containerregistry/pkg/name" - "github.com/google/go-containerregistry/pkg/v1/types" - - "github.com/sigstore/policy-controller/cmd/cosign/cli/options" - cremote "github.com/sigstore/policy-controller/pkg/cosign/remote" -) - -func BlobCmd(ctx context.Context, regOpts options.RegistryOptions, files []cremote.File, contentType, imageRef string) error { - ref, err := name.ParseReference(imageRef) - if err != nil { - return err - } - - // We normally discover the content media type by inspecting the byte stream. - // Just pass it directly if it's set on the command line. - mt := cremote.DefaultMediaTypeGetter - if contentType != "" { - mt = func(_ []byte) types.MediaType { - return types.MediaType(contentType) - } - } - - dgstAddr, err := cremote.UploadFiles(ref, files, mt, regOpts.GetRegistryClientOpts(ctx)...) - if err != nil { - return err - } - if len(files) == 0 { - return errors.New("no files uploaded?") - } - if len(files) > 1 { - fmt.Fprintf(os.Stderr, "Uploading multi-platform index to %s\n", dgstAddr) - } else { - fmt.Fprintln(os.Stderr, "Uploaded image to:") - fmt.Println(dgstAddr) - } - return nil -} diff --git a/cmd/cosign/cli/upload/wasm.go b/cmd/cosign/cli/upload/wasm.go deleted file mode 100644 index 8e1600b33..000000000 --- a/cmd/cosign/cli/upload/wasm.go +++ /dev/null @@ -1,46 +0,0 @@ -// -// Copyright 2021 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 upload - -import ( - "context" - "fmt" - "os" - - "github.com/google/go-containerregistry/pkg/name" - "github.com/google/go-containerregistry/pkg/v1/remote" - "github.com/sigstore/policy-controller/cmd/cosign/cli/options" - "github.com/sigstore/policy-controller/pkg/oci/static" - "github.com/sigstore/policy-controller/pkg/types" -) - -func WasmCmd(ctx context.Context, regOpts options.RegistryOptions, wasmPath, imageRef string) error { - b, err := os.ReadFile(wasmPath) - if err != nil { - return err - } - - ref, err := name.ParseReference(imageRef) - if err != nil { - return err - } - fmt.Fprintf(os.Stderr, "Uploading wasm file from [%s] to [%s].\n", wasmPath, ref.Name()) - img, err := static.NewFile(b, static.WithLayerMediaType(types.WasmLayerMediaType), static.WithConfigMediaType(types.WasmConfigMediaType)) - if err != nil { - return err - } - return remote.Write(ref, img, regOpts.GetRegistryClientOpts(ctx)...) -} diff --git a/cmd/cosign/cli/verify.go b/cmd/cosign/cli/verify.go deleted file mode 100644 index 44f2c5da8..000000000 --- a/cmd/cosign/cli/verify.go +++ /dev/null @@ -1,270 +0,0 @@ -// -// Copyright 2021 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 cli - -import ( - "fmt" - - "github.com/spf13/cobra" - - "github.com/sigstore/policy-controller/cmd/cosign/cli/options" - "github.com/sigstore/policy-controller/cmd/cosign/cli/verify" -) - -func Verify() *cobra.Command { - o := &options.VerifyOptions{} - - cmd := &cobra.Command{ - Use: "verify", - Short: "Verify a signature on the supplied container image", - Long: `Verify signature and annotations on an image by checking the claims -against the transparency log.`, - Example: ` cosign verify --key || [ ...] - - # verify cosign claims and signing certificates on the image - cosign verify - - # verify multiple images - cosign verify ... - - # additionally verify specified annotations - cosign verify -a key1=val1 -a key2=val2 - - # (experimental) additionally, verify with the transparency log - COSIGN_EXPERIMENTAL=1 cosign verify - - # verify image with an on-disk public key - cosign verify --key cosign.pub - - # verify image with an on-disk public key, manually specifying the - # signature digest algorithm - cosign verify --key cosign.pub --signature-digest-algorithm sha512 - - # verify image with an on-disk signed image from 'cosign save' - cosign verify --key cosign.pub --local-image - - # verify image with local certificate and certificate chain - cosign verify --cert cosign.crt --cert-chain chain.crt - - # verify image with public key provided by URL - cosign verify --key https://host.for/[FILE] - - # verify image with a key stored in an environment variable - cosign verify --key env://[ENV_VAR] - - # verify image with public key stored in Google Cloud KMS - cosign verify --key gcpkms://projects/[PROJECT]/locations/global/keyRings/[KEYRING]/cryptoKeys/[KEY] - - # verify image with public key stored in Hashicorp Vault - cosign verify --key hashivault://[KEY] - - # verify image with public key stored in a Kubernetes secret - cosign verify --key k8s://[NAMESPACE]/[KEY] - - # verify image with public key stored in GitLab with project name - cosign verify --key gitlab://[OWNER]/[PROJECT_NAME] - - # verify image with public key stored in GitLab with project id - cosign verify --key gitlab://[PROJECT_ID] `, - - Args: cobra.MinimumNArgs(1), - RunE: func(cmd *cobra.Command, args []string) error { - annotations, err := o.AnnotationsMap() - if err != nil { - return err - } - - hashAlgorithm, err := o.SignatureDigest.HashAlgorithm() - if err != nil { - return err - } - - v := verify.VerifyCommand{ - RegistryOptions: o.Registry, - CheckClaims: o.CheckClaims, - KeyRef: o.Key, - CertRef: o.CertVerify.Cert, - CertEmail: o.CertVerify.CertEmail, - CertOidcIssuer: o.CertVerify.CertOidcIssuer, - CertChain: o.CertVerify.CertChain, - EnforceSCT: o.CertVerify.EnforceSCT, - Sk: o.SecurityKey.Use, - Slot: o.SecurityKey.Slot, - Output: o.Output, - RekorURL: o.Rekor.URL, - Attachment: o.Attachment, - Annotations: annotations, - HashAlgorithm: hashAlgorithm, - SignatureRef: o.SignatureRef, - LocalImage: o.LocalImage, - } - - return v.Exec(cmd.Context(), args) - }, - } - - o.AddFlags(cmd) - return cmd -} - -func VerifyAttestation() *cobra.Command { - o := &options.VerifyAttestationOptions{} - - cmd := &cobra.Command{ - Use: "verify-attestation", - Short: "Verify an attestation on the supplied container image", - Long: `Verify an attestation on an image by checking the claims -against the transparency log.`, - Example: ` cosign verify-attestation --key || [ ...] - - # verify cosign attestations on the image - cosign verify-attestation - - # verify multiple images - cosign verify-attestation ... - - # additionally verify specified annotations - cosign verify-attestation -a key1=val1 -a key2=val2 - - # (experimental) additionally, verify with the transparency log - COSIGN_EXPERIMENTAL=1 cosign verify-attestation - - # verify image with public key - cosign verify-attestation --key cosign.pub - - # verify image attestations with an on-disk signed image from 'cosign save' - cosign verify-attestation --key cosign.pub --local-image - - # verify image with public key provided by URL - cosign verify-attestation --key https://host.for/ - - # verify image with public key stored in Google Cloud KMS - cosign verify-attestation --key gcpkms://projects//locations/global/keyRings//cryptoKeys/ - - # verify image with public key stored in Hashicorp Vault - cosign verify-attestation --key hashivault:/// - - # verify image with public key stored in GitLab with project name - cosign verify-attestation --key gitlab://[OWNER]/[PROJECT_NAME] - - # verify image with public key stored in GitLab with project id - cosign verify-attestation --key gitlab://[PROJECT_ID] - - # verify image with public key and validate attestation based on Rego policy - cosign verify-attestation --key cosign.pub --type --policy - - # verify image with public key and validate attestation based on CUE policy - cosign verify-attestation --key cosign.pub --type --policy `, - - Args: cobra.MinimumNArgs(1), - RunE: func(cmd *cobra.Command, args []string) error { - v := verify.VerifyAttestationCommand{ - RegistryOptions: o.Registry, - CheckClaims: o.CheckClaims, - CertRef: o.CertVerify.Cert, - CertEmail: o.CertVerify.CertEmail, - CertOidcIssuer: o.CertVerify.CertOidcIssuer, - CertChain: o.CertVerify.CertChain, - EnforceSCT: o.CertVerify.EnforceSCT, - KeyRef: o.Key, - Sk: o.SecurityKey.Use, - Slot: o.SecurityKey.Slot, - Output: o.Output, - RekorURL: o.Rekor.URL, - PredicateType: o.Predicate.Type, - Policies: o.Policies, - LocalImage: o.LocalImage, - } - return v.Exec(cmd.Context(), args) - }, - } - - o.AddFlags(cmd) - return cmd -} - -func VerifyBlob() *cobra.Command { - o := &options.VerifyBlobOptions{} - - cmd := &cobra.Command{ - Use: "verify-blob", - Short: "Verify a signature on the supplied blob", - Long: `Verify a signature on the supplied blob input using the specified key reference. -You may specify either a key, a certificate or a kms reference to verify against. - If you use a key or a certificate, you must specify the path to them on disk. - -The signature may be specified as a path to a file or a base64 encoded string. -The blob may be specified as a path to a file or - for stdin.`, - Example: ` cosign verify-blob (--key ||)|(--cert ) --signature - - # Verify a simple blob and message - cosign verify-blob --key cosign.pub --signature sig msg - - # Verify a simple blob with remote signature URL, both http and https schemes are supported - cosign verify-blob --key cosign.pub --signature http://host/my.sig - - # Verify a signature from an environment variable - cosign verify-blob --key cosign.pub --signature $sig msg - - # verify a signature with public key provided by URL - cosign verify-blob --key https://host.for/ --signature $sig msg - - # Verify a signature against a payload from another process using process redirection - cosign verify-blob --key cosign.pub --signature $sig <(git rev-parse HEAD) - - # Verify a signature against Azure Key Vault - cosign verify-blob --key azurekms://[VAULT_NAME][VAULT_URI]/[KEY] --signature $sig - - # Verify a signature against AWS KMS - cosign verify-blob --key awskms://[ENDPOINT]/[ID/ALIAS/ARN] --signature $sig - - # Verify a signature against Google Cloud KMS - cosign verify-blob --key gcpkms://projects/[PROJECT ID]/locations/[LOCATION]/keyRings/[KEYRING]/cryptoKeys/[KEY] --signature $sig - - # Verify a signature against Hashicorp Vault - cosign verify-blob --key hashivault://[KEY] --signature $sig - - # Verify a signature against GitLab with project name - cosign verify-blob --key gitlab://[OWNER]/[PROJECT_NAME] --signature $sig - - # Verify a signature against GitLab with project id - cosign verify-blob --key gitlab://[PROJECT_ID] --signature $sig - - # Verify a signature against a certificate - cosign verify-blob --cert --signature $sig -`, - - Args: cobra.ExactArgs(1), - 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, - } - if err := verify.VerifyBlobCmd(cmd.Context(), ko, o.CertVerify.Cert, - o.CertVerify.CertEmail, o.CertVerify.CertOidcIssuer, o.CertVerify.CertChain, - o.Signature, args[0], o.CertVerify.EnforceSCT); err != nil { - return fmt.Errorf("verifying blob %s: %w", args, err) - } - return nil - }, - } - - o.AddFlags(cmd) - return cmd -} diff --git a/cmd/cosign/cli/verify/verify.go b/cmd/cosign/cli/verify/verify.go deleted file mode 100644 index bb75aaa42..000000000 --- a/cmd/cosign/cli/verify/verify.go +++ /dev/null @@ -1,336 +0,0 @@ -// -// Copyright 2021 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 verify - -import ( - "bytes" - "context" - "crypto" - "crypto/x509" - "encoding/base64" - "encoding/json" - "errors" - "flag" - "fmt" - "os" - - "github.com/google/go-containerregistry/pkg/name" - - "github.com/sigstore/policy-controller/cmd/cosign/cli/fulcio" - "github.com/sigstore/policy-controller/cmd/cosign/cli/options" - "github.com/sigstore/policy-controller/cmd/cosign/cli/rekor" - "github.com/sigstore/policy-controller/cmd/cosign/cli/sign" - "github.com/sigstore/policy-controller/pkg/blob" - "github.com/sigstore/policy-controller/pkg/cosign" - "github.com/sigstore/policy-controller/pkg/cosign/pivkey" - "github.com/sigstore/policy-controller/pkg/cosign/pkcs11key" - "github.com/sigstore/policy-controller/pkg/oci" - sigs "github.com/sigstore/policy-controller/pkg/signature" - "github.com/sigstore/sigstore/pkg/cryptoutils" - "github.com/sigstore/sigstore/pkg/signature" - "github.com/sigstore/sigstore/pkg/signature/payload" -) - -// VerifyCommand verifies a signature on a supplied container image -// nolint -type VerifyCommand struct { - options.RegistryOptions - CheckClaims bool - KeyRef string - CertRef string - CertEmail string - CertOidcIssuer string - CertChain string - EnforceSCT bool - Sk bool - Slot string - Output string - RekorURL string - Attachment string - Annotations sigs.AnnotationsMap - SignatureRef string - HashAlgorithm crypto.Hash - LocalImage bool -} - -// Exec runs the verification command -func (c *VerifyCommand) Exec(ctx context.Context, images []string) (err error) { - if len(images) == 0 { - return flag.ErrHelp - } - - switch c.Attachment { - case "sbom", "": - break - default: - return flag.ErrHelp - } - - // always default to sha256 if the algorithm hasn't been explicitly set - if c.HashAlgorithm == 0 { - c.HashAlgorithm = crypto.SHA256 - } - - if !options.OneOf(c.KeyRef, c.CertRef, c.Sk) && !options.EnableExperimental() { - return &options.PubKeyParseError{} - } - ociremoteOpts, err := c.ClientOpts(ctx) - if err != nil { - return fmt.Errorf("constructing client options: %w", err) - } - co := &cosign.CheckOpts{ - Annotations: c.Annotations.Annotations, - RegistryClientOpts: ociremoteOpts, - CertEmail: c.CertEmail, - CertOidcIssuer: c.CertOidcIssuer, - EnforceSCT: c.EnforceSCT, - SignatureRef: c.SignatureRef, - } - if c.CheckClaims { - co.ClaimVerifier = cosign.SimpleClaimVerifier - } - if options.EnableExperimental() { - if c.RekorURL != "" { - rekorClient, err := rekor.NewClient(c.RekorURL) - if err != nil { - return fmt.Errorf("creating Rekor client: %w", err) - } - co.RekorClient = rekorClient - } - co.RootCerts, err = fulcio.GetRoots() - if err != nil { - return fmt.Errorf("getting Fulcio roots: %w", err) - } - co.IntermediateCerts, err = fulcio.GetIntermediates() - if err != nil { - return fmt.Errorf("getting Fulcio intermediates: %w", err) - } - } - keyRef := c.KeyRef - certRef := c.CertRef - - // Keys are optional! - var pubKey signature.Verifier - switch { - case keyRef != "": - pubKey, err = sigs.PublicKeyFromKeyRefWithHashAlgo(ctx, keyRef, c.HashAlgorithm) - if err != nil { - return fmt.Errorf("loading public key: %w", err) - } - pkcs11Key, ok := pubKey.(*pkcs11key.Key) - if ok { - defer pkcs11Key.Close() - } - case c.Sk: - sk, err := pivkey.GetKeyWithSlot(c.Slot) - if err != nil { - return fmt.Errorf("opening piv token: %w", err) - } - defer sk.Close() - pubKey, err = sk.Verifier() - if err != nil { - return fmt.Errorf("initializing piv token verifier: %w", err) - } - case certRef != "": - cert, err := loadCertFromFileOrURL(c.CertRef) - if err != nil { - return err - } - if c.CertChain == "" { - err = cosign.CheckCertificatePolicy(cert, co) - if err != nil { - return err - } - pubKey, err = signature.LoadVerifier(cert.PublicKey, crypto.SHA256) - if err != nil { - return err - } - } else { - // Verify certificate with chain - chain, err := loadCertChainFromFileOrURL(c.CertChain) - if err != nil { - return err - } - pubKey, err = cosign.ValidateAndUnpackCertWithChain(cert, chain, co) - if err != nil { - return err - } - } - } - co.SigVerifier = pubKey - - // NB: There are only 2 kinds of verification right now: - // 1. You gave us the public key explicitly to verify against so co.SigVerifier is non-nil or, - // 2. We're going to find an x509 certificate on the signature and verify against Fulcio root trust - // TODO(nsmith5): Refactor this verification logic to pass back _how_ verification - // was performed so we don't need to use this fragile logic here. - fulcioVerified := (co.SigVerifier == nil) - - for _, img := range images { - if c.LocalImage { - verified, bundleVerified, err := cosign.VerifyLocalImageSignatures(ctx, img, co) - if err != nil { - return err - } - PrintVerificationHeader(img, co, bundleVerified, fulcioVerified) - PrintVerification(img, verified, c.Output) - } else { - ref, err := name.ParseReference(img) - if err != nil { - return fmt.Errorf("parsing reference: %w", err) - } - ref, err = sign.GetAttachedImageRef(ref, c.Attachment, ociremoteOpts...) - if err != nil { - return fmt.Errorf("resolving attachment type %s for image %s: %w", c.Attachment, img, err) - } - - verified, bundleVerified, err := cosign.VerifyImageSignatures(ctx, ref, co) - if err != nil { - return err - } - - PrintVerificationHeader(ref.Name(), co, bundleVerified, fulcioVerified) - PrintVerification(ref.Name(), verified, c.Output) - } - } - - return nil -} - -func PrintVerificationHeader(imgRef string, co *cosign.CheckOpts, bundleVerified, fulcioVerified bool) { - fmt.Fprintf(os.Stderr, "\nVerification for %s --\n", imgRef) - fmt.Fprintln(os.Stderr, "The following checks were performed on each of these signatures:") - if co.ClaimVerifier != nil { - if co.Annotations != nil { - fmt.Fprintln(os.Stderr, " - The specified annotations were verified.") - } - fmt.Fprintln(os.Stderr, " - The cosign claims were validated") - } - if bundleVerified { - fmt.Fprintln(os.Stderr, " - Existence of the claims in the transparency log was verified offline") - } else if co.RekorClient != nil { - fmt.Fprintln(os.Stderr, " - The claims were present in the transparency log") - fmt.Fprintln(os.Stderr, " - The signatures were integrated into the transparency log when the certificate was valid") - } - if co.SigVerifier != nil { - fmt.Fprintln(os.Stderr, " - The signatures were verified against the specified public key") - } - if fulcioVerified { - fmt.Fprintln(os.Stderr, " - Any certificates were verified against the Fulcio roots.") - } -} - -// PrintVerification logs details about the verification to stdout -func PrintVerification(imgRef string, verified []oci.Signature, output string) { - switch output { - case "text": - for _, sig := range verified { - if cert, err := sig.Cert(); err == nil && cert != nil { - fmt.Fprintln(os.Stderr, "Certificate subject: ", sigs.CertSubject(cert)) - if issuerURL := sigs.CertIssuerExtension(cert); issuerURL != "" { - fmt.Fprintln(os.Stderr, "Certificate issuer URL: ", issuerURL) - } - } - - p, err := sig.Payload() - if err != nil { - fmt.Fprintf(os.Stderr, "Error fetching payload: %v", err) - return - } - fmt.Println(string(p)) - } - - default: - var outputKeys []payload.SimpleContainerImage - for _, sig := range verified { - p, err := sig.Payload() - if err != nil { - fmt.Fprintf(os.Stderr, "Error fetching payload: %v", err) - return - } - - ss := payload.SimpleContainerImage{} - if err := json.Unmarshal(p, &ss); err != nil { - fmt.Println("error decoding the payload:", err.Error()) - return - } - - if cert, err := sig.Cert(); err == nil && cert != nil { - if ss.Optional == nil { - ss.Optional = make(map[string]interface{}) - } - ss.Optional["Subject"] = sigs.CertSubject(cert) - if issuerURL := sigs.CertIssuerExtension(cert); issuerURL != "" { - ss.Optional["Issuer"] = issuerURL - } - } - if bundle, err := sig.Bundle(); err == nil && bundle != nil { - if ss.Optional == nil { - ss.Optional = make(map[string]interface{}) - } - ss.Optional["Bundle"] = bundle - } - - outputKeys = append(outputKeys, ss) - } - - b, err := json.Marshal(outputKeys) - if err != nil { - fmt.Println("error when generating the output:", err.Error()) - return - } - - fmt.Printf("\n%s\n", string(b)) - } -} - -func loadCertFromFileOrURL(path string) (*x509.Certificate, error) { - pems, err := blob.LoadFileOrURL(path) - if err != nil { - return nil, err - } - return loadCertFromPEM(pems) -} - -func loadCertFromPEM(pems []byte) (*x509.Certificate, error) { - var out []byte - out, err := base64.StdEncoding.DecodeString(string(pems)) - if err != nil { - // not a base64 - out = pems - } - - certs, err := cryptoutils.UnmarshalCertificatesFromPEM(out) - if err != nil { - return nil, err - } - if len(certs) == 0 { - return nil, errors.New("no certs found in pem file") - } - return certs[0], nil -} - -func loadCertChainFromFileOrURL(path string) ([]*x509.Certificate, error) { - pems, err := blob.LoadFileOrURL(path) - if err != nil { - return nil, err - } - certs, err := cryptoutils.LoadCertificatesFromPEM(bytes.NewReader(pems)) - if err != nil { - return nil, err - } - return certs, nil -} diff --git a/cmd/cosign/cli/verify/verify_attestation.go b/cmd/cosign/cli/verify/verify_attestation.go deleted file mode 100644 index d713de66f..000000000 --- a/cmd/cosign/cli/verify/verify_attestation.go +++ /dev/null @@ -1,237 +0,0 @@ -// -// Copyright 2021 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 verify - -import ( - "context" - "crypto" - "errors" - "flag" - "fmt" - "os" - "path/filepath" - - "github.com/google/go-containerregistry/pkg/name" - "github.com/sigstore/policy-controller/pkg/cosign/pkcs11key" - "github.com/sigstore/policy-controller/pkg/cosign/rego" - "github.com/sigstore/policy-controller/pkg/oci" - "github.com/sigstore/sigstore/pkg/signature" - - "github.com/sigstore/policy-controller/cmd/cosign/cli/fulcio" - "github.com/sigstore/policy-controller/cmd/cosign/cli/options" - "github.com/sigstore/policy-controller/cmd/cosign/cli/rekor" - "github.com/sigstore/policy-controller/pkg/cosign" - "github.com/sigstore/policy-controller/pkg/cosign/cue" - "github.com/sigstore/policy-controller/pkg/cosign/pivkey" - "github.com/sigstore/policy-controller/pkg/policy" - sigs "github.com/sigstore/policy-controller/pkg/signature" -) - -// VerifyAttestationCommand verifies a signature on a supplied container image -// nolint -type VerifyAttestationCommand struct { - options.RegistryOptions - CheckClaims bool - KeyRef string - CertRef string - CertEmail string - CertOidcIssuer string - CertChain string - EnforceSCT bool - Sk bool - Slot string - Output string - RekorURL string - PredicateType string - Policies []string - LocalImage bool -} - -// Exec runs the verification command -func (c *VerifyAttestationCommand) Exec(ctx context.Context, images []string) (err error) { - if len(images) == 0 { - return flag.ErrHelp - } - - if !options.OneOf(c.KeyRef, c.Sk, c.CertRef) && !options.EnableExperimental() { - return &options.PubKeyParseError{} - } - - ociremoteOpts, err := c.ClientOpts(ctx) - if err != nil { - return fmt.Errorf("constructing client options: %w", err) - } - co := &cosign.CheckOpts{ - RegistryClientOpts: ociremoteOpts, - CertEmail: c.CertEmail, - CertOidcIssuer: c.CertOidcIssuer, - EnforceSCT: c.EnforceSCT, - } - if c.CheckClaims { - co.ClaimVerifier = cosign.IntotoSubjectClaimVerifier - } - if options.EnableExperimental() { - if c.RekorURL != "" { - rekorClient, err := rekor.NewClient(c.RekorURL) - if err != nil { - return fmt.Errorf("creating Rekor client: %w", err) - } - co.RekorClient = rekorClient - } - co.RootCerts, err = fulcio.GetRoots() - if err != nil { - return fmt.Errorf("getting Fulcio roots: %w", err) - } - co.IntermediateCerts, err = fulcio.GetIntermediates() - if err != nil { - return fmt.Errorf("getting Fulcio intermediates: %w", err) - } - } - keyRef := c.KeyRef - - // Keys are optional! - switch { - case keyRef != "": - co.SigVerifier, err = sigs.PublicKeyFromKeyRef(ctx, keyRef) - if err != nil { - return fmt.Errorf("loading public key: %w", err) - } - pkcs11Key, ok := co.SigVerifier.(*pkcs11key.Key) - if ok { - defer pkcs11Key.Close() - } - case c.Sk: - sk, err := pivkey.GetKeyWithSlot(c.Slot) - if err != nil { - return fmt.Errorf("opening piv token: %w", err) - } - defer sk.Close() - co.SigVerifier, err = sk.Verifier() - if err != nil { - return fmt.Errorf("initializing piv token verifier: %w", err) - } - case c.CertRef != "": - cert, err := loadCertFromFileOrURL(c.CertRef) - if err != nil { - return fmt.Errorf("loading certificate from reference: %w", err) - } - if c.CertChain == "" { - err = cosign.CheckCertificatePolicy(cert, co) - if err != nil { - return err - } - co.SigVerifier, err = signature.LoadVerifier(cert.PublicKey, crypto.SHA256) - if err != nil { - return fmt.Errorf("creating certificate verifier: %w", err) - } - } else { - // Verify certificate with chain - chain, err := loadCertChainFromFileOrURL(c.CertChain) - if err != nil { - return err - } - co.SigVerifier, err = cosign.ValidateAndUnpackCertWithChain(cert, chain, co) - if err != nil { - return fmt.Errorf("creating certificate verifier: %w", err) - } - } - } - - // NB: There are only 2 kinds of verification right now: - // 1. You gave us the public key explicitly to verify against so co.SigVerifier is non-nil or, - // 2. We're going to find an x509 certificate on the signature and verify against Fulcio root trust - // TODO(nsmith5): Refactor this verification logic to pass back _how_ verification - // was performed so we don't need to use this fragile logic here. - fulcioVerified := (co.SigVerifier == nil) - - for _, imageRef := range images { - var verified []oci.Signature - var bundleVerified bool - - if c.LocalImage { - verified, bundleVerified, err = cosign.VerifyLocalImageAttestations(ctx, imageRef, co) - if err != nil { - return err - } - } else { - ref, err := name.ParseReference(imageRef) - if err != nil { - return err - } - - verified, bundleVerified, err = cosign.VerifyImageAttestations(ctx, ref, co) - if err != nil { - return err - } - } - - var cuePolicies, regoPolicies []string - - for _, policy := range c.Policies { - switch filepath.Ext(policy) { - case ".rego": - regoPolicies = append(regoPolicies, policy) - case ".cue": - cuePolicies = append(cuePolicies, policy) - default: - return errors.New("invalid policy format, expected .cue or .rego") - } - } - - var validationErrors []error - for _, vp := range verified { - payload, err := policy.AttestationToPayloadJSON(ctx, c.PredicateType, vp) - if err != nil { - return fmt.Errorf("converting to consumable policy validation: %w", err) - } - if len(payload) == 0 { - // This is not the predicate type we're looking for. - continue - } - - if len(cuePolicies) > 0 { - fmt.Fprintf(os.Stderr, "will be validating against CUE policies: %v\n", cuePolicies) - cueValidationErr := cue.ValidateJSON(payload, cuePolicies) - if cueValidationErr != nil { - validationErrors = append(validationErrors, cueValidationErr) - } - } - - if len(regoPolicies) > 0 { - fmt.Fprintf(os.Stderr, "will be validating against Rego policies: %v\n", regoPolicies) - regoValidationErrs := rego.ValidateJSON(payload, regoPolicies) - if len(regoValidationErrs) > 0 { - validationErrors = append(validationErrors, regoValidationErrs...) - } - } - } - - if len(validationErrors) > 0 { - fmt.Fprintf(os.Stderr, "There are %d number of errors occurred during the validation:\n", len(validationErrors)) - for _, v := range validationErrors { - _, _ = fmt.Fprintf(os.Stderr, "- %v\n", v) - } - return fmt.Errorf("%d validation errors occurred", len(validationErrors)) - } - - // TODO: add CUE validation report to `PrintVerificationHeader`. - PrintVerificationHeader(imageRef, co, bundleVerified, fulcioVerified) - // The attestations are always JSON, so use the raw "text" mode for outputting them instead of conversion - PrintVerification(imageRef, verified, "text") - } - - return nil -} diff --git a/cmd/cosign/cli/verify/verify_blob.go b/cmd/cosign/cli/verify/verify_blob.go deleted file mode 100644 index 028e07d3c..000000000 --- a/cmd/cosign/cli/verify/verify_blob.go +++ /dev/null @@ -1,452 +0,0 @@ -// -// Copyright 2021 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 verify - -import ( - "bytes" - "context" - "crypto" - _ "crypto/sha256" // for `crypto.SHA256` - "crypto/x509" - "encoding/base64" - "encoding/hex" - "encoding/json" - "errors" - "fmt" - "io" - "os" - "time" - - "github.com/go-openapi/runtime" - ssldsse "github.com/secure-systems-lab/go-securesystemslib/dsse" - "github.com/sigstore/policy-controller/cmd/cosign/cli/fulcio" - "github.com/sigstore/policy-controller/cmd/cosign/cli/options" - "github.com/sigstore/policy-controller/cmd/cosign/cli/rekor" - "github.com/sigstore/policy-controller/pkg/blob" - "github.com/sigstore/policy-controller/pkg/cosign" - "github.com/sigstore/policy-controller/pkg/cosign/pivkey" - "github.com/sigstore/policy-controller/pkg/cosign/pkcs11key" - "github.com/sigstore/policy-controller/pkg/cosign/tuf" - sigs "github.com/sigstore/policy-controller/pkg/signature" - - ctypes "github.com/sigstore/policy-controller/pkg/types" - "github.com/sigstore/rekor/pkg/generated/client" - "github.com/sigstore/rekor/pkg/generated/models" - "github.com/sigstore/rekor/pkg/types" - hashedrekord "github.com/sigstore/rekor/pkg/types/hashedrekord/v0.0.1" - rekord "github.com/sigstore/rekor/pkg/types/rekord/v0.0.1" - "github.com/sigstore/sigstore/pkg/cryptoutils" - "github.com/sigstore/sigstore/pkg/signature" - "github.com/sigstore/sigstore/pkg/signature/dsse" - signatureoptions "github.com/sigstore/sigstore/pkg/signature/options" -) - -func isb64(data []byte) bool { - _, err := base64.StdEncoding.DecodeString(string(data)) - return err == nil -} - -// nolint -func VerifyBlobCmd(ctx context.Context, ko options.KeyOpts, certRef, certEmail, - certOidcIssuer, certChain, sigRef, blobRef string, enforceSCT bool) error { - var verifier signature.Verifier - var cert *x509.Certificate - - if !options.OneOf(ko.KeyRef, ko.Sk, certRef) && !options.EnableExperimental() && ko.BundlePath == "" { - return &options.PubKeyParseError{} - } - - sig, b64sig, err := signatures(sigRef, ko.BundlePath) - if err != nil { - return err - } - - blobBytes, err := payloadBytes(blobRef) - if err != nil { - return err - } - - // Keys are optional! - switch { - case ko.KeyRef != "": - verifier, err = sigs.PublicKeyFromKeyRef(ctx, ko.KeyRef) - if err != nil { - return fmt.Errorf("loading public key: %w", err) - } - pkcs11Key, ok := verifier.(*pkcs11key.Key) - if ok { - defer pkcs11Key.Close() - } - case ko.Sk: - sk, err := pivkey.GetKeyWithSlot(ko.Slot) - if err != nil { - return fmt.Errorf("opening piv token: %w", err) - } - defer sk.Close() - verifier, err = sk.Verifier() - if err != nil { - return fmt.Errorf("loading public key from token: %w", err) - } - case certRef != "": - cert, err = loadCertFromFileOrURL(certRef) - if err != nil { - return err - } - co := &cosign.CheckOpts{ - CertEmail: certEmail, - CertOidcIssuer: certOidcIssuer, - EnforceSCT: enforceSCT, - } - if certChain == "" { - err = cosign.CheckCertificatePolicy(cert, co) - if err != nil { - return err - } - verifier, err = signature.LoadVerifier(cert.PublicKey, crypto.SHA256) - if err != nil { - return err - } - } else { - // Verify certificate with chain - chain, err := loadCertChainFromFileOrURL(certChain) - if err != nil { - return err - } - verifier, err = cosign.ValidateAndUnpackCertWithChain(cert, chain, co) - if err != nil { - return err - } - } - case ko.BundlePath != "": - b, err := cosign.FetchLocalSignedPayloadFromPath(ko.BundlePath) - if err != nil { - return err - } - if b.Cert == "" { - return fmt.Errorf("bundle does not contain cert for verification, please provide public key") - } - // cert can either be a cert or public key - certBytes := []byte(b.Cert) - if isb64(certBytes) { - certBytes, _ = base64.StdEncoding.DecodeString(b.Cert) - } - cert, err = loadCertFromPEM(certBytes) - if err != nil { - // check if cert is actually a public key - verifier, err = sigs.LoadPublicKeyRaw(certBytes, crypto.SHA256) - } else { - verifier, err = signature.LoadVerifier(cert.PublicKey, crypto.SHA256) - } - if err != nil { - return err - } - case options.EnableExperimental(): - rClient, err := rekor.NewClient(ko.RekorURL) - if err != nil { - return err - } - - uuids, err := cosign.FindTLogEntriesByPayload(ctx, rClient, blobBytes) - if err != nil { - return err - } - - if len(uuids) == 0 { - return errors.New("could not find a tlog entry for provided blob") - } - return verifySigByUUID(ctx, ko, rClient, certEmail, certOidcIssuer, sig, b64sig, uuids, blobBytes, enforceSCT) - } - - // Use the DSSE verifier if the payload is a DSSE with the In-Toto format. - if isIntotoDSSE(blobBytes) { - verifier = dsse.WrapVerifier(verifier) - } - - // verify the signature - if err := verifier.VerifySignature(bytes.NewReader([]byte(sig)), bytes.NewReader(blobBytes)); err != nil { - return err - } - - // verify the rekor entry - if err := verifyRekorEntry(ctx, ko, nil, verifier, cert, b64sig, blobBytes); err != nil { - return err - } - - fmt.Fprintln(os.Stderr, "Verified OK") - return nil -} - -func verifySigByUUID(ctx context.Context, ko options.KeyOpts, rClient *client.Rekor, certEmail, certOidcIssuer, sig, b64sig string, - uuids []string, blobBytes []byte, enforceSCT bool) error { - var validSigExists bool - for _, u := range uuids { - tlogEntry, err := cosign.GetTlogEntry(ctx, rClient, u) - if err != nil { - continue - } - - certs, err := extractCerts(tlogEntry) - if err != nil { - continue - } - - co := &cosign.CheckOpts{ - CertEmail: certEmail, - CertOidcIssuer: certOidcIssuer, - EnforceSCT: enforceSCT, - } - - co.RootCerts, err = fulcio.GetRoots() - if err != nil { - return fmt.Errorf("getting Fulcio roots: %w", err) - } - co.IntermediateCerts, err = fulcio.GetIntermediates() - if err != nil { - return fmt.Errorf("getting Fulcio intermediates: %w", err) - } - - cert := certs[0] - verifier, err := cosign.ValidateAndUnpackCert(cert, co) - if err != nil { - continue - } - // Use the DSSE verifier if the payload is a DSSE with the In-Toto format. - if isIntotoDSSE(blobBytes) { - verifier = dsse.WrapVerifier(verifier) - } - // verify the signature - if err := verifier.VerifySignature(bytes.NewReader([]byte(sig)), bytes.NewReader(blobBytes)); err != nil { - continue - } - - // verify the rekor entry - if err := verifyRekorEntry(ctx, ko, tlogEntry, verifier, cert, b64sig, blobBytes); err != nil { - continue - } - validSigExists = true - } - if !validSigExists { - fmt.Fprintln(os.Stderr, `WARNING: No valid entries were found in rekor to verify this blob. - -Transparency log support for blobs is experimental, and occasionally an entry isn't found even if one exists. - -We recommend requesting the certificate/signature from the original signer of this blob and manually verifying with cosign verify-blob --cert [cert] --signature [signature].`) - return fmt.Errorf("could not find a valid tlog entry for provided blob, found %d invalid entries", len(uuids)) - } - fmt.Fprintln(os.Stderr, "Verified OK") - return nil -} - -// signatures returns the raw signature and the base64 encoded signature -func signatures(sigRef string, bundlePath string) (string, string, error) { - var targetSig []byte - var err error - switch { - case sigRef != "": - targetSig, err = blob.LoadFileOrURL(sigRef) - if err != nil { - if !os.IsNotExist(err) { - // ignore if file does not exist, it can be a base64 encoded string as well - return "", "", err - } - targetSig = []byte(sigRef) - } - case bundlePath != "": - b, err := cosign.FetchLocalSignedPayloadFromPath(bundlePath) - if err != nil { - return "", "", err - } - targetSig = []byte(b.Base64Signature) - default: - return "", "", fmt.Errorf("missing flag '--signature'") - } - - var sig, b64sig string - if isb64(targetSig) { - b64sig = string(targetSig) - sigBytes, _ := base64.StdEncoding.DecodeString(b64sig) - sig = string(sigBytes) - } else { - sig = string(targetSig) - b64sig = base64.StdEncoding.EncodeToString(targetSig) - } - return sig, b64sig, nil -} - -func payloadBytes(blobRef string) ([]byte, error) { - var blobBytes []byte - var err error - if blobRef == "-" { - blobBytes, err = io.ReadAll(os.Stdin) - } else { - blobBytes, err = blob.LoadFileOrURL(blobRef) - } - if err != nil { - return nil, err - } - return blobBytes, nil -} - -func verifyRekorEntry(ctx context.Context, ko options.KeyOpts, e *models.LogEntryAnon, pubKey signature.Verifier, cert *x509.Certificate, b64sig string, blobBytes []byte) error { - // TODO: This can be moved below offline bundle verification when SIGSTORE_TRUST_REKOR_API_PUBLIC_KEY - // is removed. - rekorClient, err := rekor.NewClient(ko.RekorURL) - if err != nil { - return err - } - - // If we have a bundle with a rekor entry, let's first try to verify offline - if ko.BundlePath != "" { - if err := verifyRekorBundle(ctx, ko.BundlePath, cert, rekorClient); err == nil { - fmt.Fprintf(os.Stderr, "tlog entry verified offline\n") - return nil - } - } - if !options.EnableExperimental() { - return nil - } - - // Only fetch from rekor tlog if we don't already have the entry. - if e == nil { - var pubBytes []byte - if pubKey != nil { - pubBytes, err = sigs.PublicKeyPem(pubKey, signatureoptions.WithContext(ctx)) - if err != nil { - return err - } - } - if cert != nil { - pubBytes, err = cryptoutils.MarshalCertificateToPEM(cert) - if err != nil { - return err - } - } - e, err = cosign.FindTlogEntry(ctx, rekorClient, b64sig, blobBytes, pubBytes) - if err != nil { - return err - } - } - - if err := cosign.VerifyTLogEntry(ctx, rekorClient, e); err != nil { - return nil - } - - uuid, err := cosign.ComputeLeafHash(e) - if err != nil { - return err - } - - fmt.Fprintf(os.Stderr, "tlog entry verified with uuid: %s index: %d\n", hex.EncodeToString(uuid), *e.Verification.InclusionProof.LogIndex) - if cert == nil { - return nil - } - // if we have a cert, we should check expiry - return cosign.CheckExpiry(cert, time.Unix(*e.IntegratedTime, 0)) -} - -func verifyRekorBundle(ctx context.Context, bundlePath string, cert *x509.Certificate, rekorClient *client.Rekor) error { - b, err := cosign.FetchLocalSignedPayloadFromPath(bundlePath) - if err != nil { - return err - } - if b.Bundle == nil { - return fmt.Errorf("rekor entry is not available") - } - publicKeys, err := cosign.GetRekorPubs(ctx, rekorClient) - if err != nil { - return fmt.Errorf("retrieving rekor public key: %w", err) - } - - pubKey, ok := publicKeys[b.Bundle.Payload.LogID] - if !ok { - return errors.New("rekor log public key not found for payload") - } - err = cosign.VerifySET(b.Bundle.Payload, b.Bundle.SignedEntryTimestamp, pubKey.PubKey) - if err != nil { - return err - } - if pubKey.Status != tuf.Active { - fmt.Fprintf(os.Stderr, "**Info** Successfully verified Rekor entry using an expired verification key\n") - } - - if cert == nil { - return nil - } - it := time.Unix(b.Bundle.Payload.IntegratedTime, 0) - return cosign.CheckExpiry(cert, it) -} - -func extractCerts(e *models.LogEntryAnon) ([]*x509.Certificate, error) { - b, err := base64.StdEncoding.DecodeString(e.Body.(string)) - if err != nil { - return nil, err - } - - pe, err := models.UnmarshalProposedEntry(bytes.NewReader(b), runtime.JSONConsumer()) - if err != nil { - return nil, err - } - - eimpl, err := types.NewEntry(pe) - if err != nil { - return nil, err - } - - var publicKeyB64 []byte - switch e := eimpl.(type) { - case *rekord.V001Entry: - publicKeyB64, err = e.RekordObj.Signature.PublicKey.Content.MarshalText() - if err != nil { - return nil, err - } - case *hashedrekord.V001Entry: - publicKeyB64, err = e.HashedRekordObj.Signature.PublicKey.Content.MarshalText() - if err != nil { - return nil, err - } - default: - return nil, errors.New("unexpected tlog entry type") - } - - publicKey, err := base64.StdEncoding.DecodeString(string(publicKeyB64)) - if err != nil { - return nil, err - } - - certs, err := cryptoutils.UnmarshalCertificatesFromPEM(publicKey) - if err != nil { - return nil, err - } - - if len(certs) == 0 { - return nil, errors.New("no certs found in pem tlog") - } - - return certs, err -} - -// 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 -} diff --git a/cmd/cosign/cli/verify/verify_blob_test.go b/cmd/cosign/cli/verify/verify_blob_test.go deleted file mode 100644 index 1eaba3986..000000000 --- a/cmd/cosign/cli/verify/verify_blob_test.go +++ /dev/null @@ -1,143 +0,0 @@ -// Copyright 2022 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 verify - -import ( - "encoding/base64" - "encoding/json" - "io/ioutil" - "path/filepath" - "testing" - - "github.com/secure-systems-lab/go-securesystemslib/dsse" - "github.com/sigstore/policy-controller/pkg/cosign" -) - -func TestSignaturesRef(t *testing.T) { - sig := "a==" - b64sig := "YT09" - tests := []struct { - description string - sigRef string - shouldErr bool - }{ - { - description: "raw sig", - sigRef: sig, - }, - { - description: "encoded sig", - sigRef: b64sig, - }, { - description: "empty ref", - shouldErr: true, - }, - } - - for _, test := range tests { - t.Run(test.description, func(t *testing.T) { - gotSig, gotb64Sig, err := signatures(test.sigRef, "") - if test.shouldErr && err != nil { - return - } - if test.shouldErr { - t.Fatal("should have received an error") - } - if gotSig != sig { - t.Fatalf("unexpected signature, expected: %s got: %s", sig, gotSig) - } - if gotb64Sig != b64sig { - t.Fatalf("unexpected encoded signature, expected: %s got: %s", b64sig, gotb64Sig) - } - }) - } -} - -func TestSignaturesBundle(t *testing.T) { - td := t.TempDir() - fp := filepath.Join(td, "file") - - sig := "a==" - b64sig := "YT09" - - // save as a LocalSignedPayload to the file - lsp := cosign.LocalSignedPayload{ - Base64Signature: b64sig, - } - contents, err := json.Marshal(lsp) - if err != nil { - t.Fatal(err) - } - if err := ioutil.WriteFile(fp, contents, 0644); err != nil { - t.Fatal(err) - } - - gotSig, gotb64Sig, err := signatures("", fp) - if err != nil { - t.Fatal(err) - } - if gotSig != sig { - t.Fatalf("unexpected signature, expected: %s got: %s", sig, gotSig) - } - if gotb64Sig != b64sig { - t.Fatalf("unexpected encoded signature, expected: %s got: %s", b64sig, gotb64Sig) - } -} - -func TestIsIntotoDSSEWithEnvelopes(t *testing.T) { - tts := []struct { - envelope dsse.Envelope - isIntotoDSSE bool - }{ - { - envelope: dsse.Envelope{ - PayloadType: "application/vnd.in-toto+json", - Payload: base64.StdEncoding.EncodeToString([]byte("This is a test")), - Signatures: []dsse.Signature{}, - }, - isIntotoDSSE: true, - }, - } - for _, tt := range tts { - envlopeBytes, _ := json.Marshal(tt.envelope) - got := isIntotoDSSE(envlopeBytes) - if got != tt.isIntotoDSSE { - t.Fatalf("unexpected envelope content") - } - } -} - -func TestIsIntotoDSSEWithBytes(t *testing.T) { - tts := []struct { - envelope []byte - isIntotoDSSE bool - }{ - { - envelope: []byte("This is no valid"), - isIntotoDSSE: false, - }, - { - envelope: []byte("MEUCIQDBmE1ZRFjUVic1hzukesJlmMFG1JqWWhcthnhawTeBNQIga3J9/WKsNlSZaySnl8V360bc2S8dIln2/qo186EfjHA="), - isIntotoDSSE: false, - }, - } - for _, tt := range tts { - envlopeBytes, _ := json.Marshal(tt.envelope) - got := isIntotoDSSE(envlopeBytes) - if got != tt.isIntotoDSSE { - t.Fatalf("unexpected envelope content") - } - } -} diff --git a/cmd/cosign/main.go b/cmd/cosign/main.go deleted file mode 100644 index 27681ef87..000000000 --- a/cmd/cosign/main.go +++ /dev/null @@ -1,54 +0,0 @@ -// Copyright 2021 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 main - -import ( - "fmt" - "log" - "os" - "strings" - - "github.com/sigstore/policy-controller/cmd/cosign/cli" - - // Register the provider-specific plugins - _ "github.com/sigstore/sigstore/pkg/signature/kms/aws" - _ "github.com/sigstore/sigstore/pkg/signature/kms/azure" - _ "github.com/sigstore/sigstore/pkg/signature/kms/gcp" - _ "github.com/sigstore/sigstore/pkg/signature/kms/hashivault" -) - -func main() { - // Fix up flags to POSIX standard flags. - for i, arg := range os.Args { - if (strings.HasPrefix(arg, "-") && len(arg) == 2) || (strings.HasPrefix(arg, "--") && len(arg) >= 4) { - continue - } - if strings.HasPrefix(arg, "--") && len(arg) == 3 { - // Handle --o, convert to -o - newArg := fmt.Sprintf("-%c", arg[2]) - fmt.Fprintf(os.Stderr, "WARNING: the flag %s is deprecated and will be removed in a future release. Please use the flag %s.\n", arg, newArg) - os.Args[i] = newArg - } else if strings.HasPrefix(arg, "-") { - // Handle -output, convert to --output - newArg := fmt.Sprintf("-%s", arg) - fmt.Fprintf(os.Stderr, "WARNING: the flag %s is deprecated and will be removed in a future release. Please use the flag %s.\n", arg, newArg) - os.Args[i] = newArg - } - } - - if err := cli.New().Execute(); err != nil { - log.Fatalf("error during command execution: %v", err) - } -} diff --git a/cmd/fig/fig.go b/cmd/fig/fig.go deleted file mode 100644 index dd666e789..000000000 --- a/cmd/fig/fig.go +++ /dev/null @@ -1,27 +0,0 @@ -// Copyright 2022 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 main - -import ( - "fmt" - - "github.com/sigstore/policy-controller/cmd/cosign/cli" - genFigSpec "github.com/withfig/autocomplete-tools/packages/cobra" -) - -func main() { - spec := genFigSpec.MakeFigSpec(cli.New()) - fmt.Println(spec.ToTypescript()) -} diff --git a/cmd/help/main.go b/cmd/help/main.go deleted file mode 100644 index 233d6b5e9..000000000 --- a/cmd/help/main.go +++ /dev/null @@ -1,42 +0,0 @@ -// Copyright 2021 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 main - -import ( - "fmt" - "os" - - "github.com/sigstore/policy-controller/cmd/cosign/cli" - "github.com/spf13/cobra" - "github.com/spf13/cobra/doc" -) - -func main() { - var dir string - root := &cobra.Command{ - Use: "gendoc", - Short: "Generate cosign's help docs", - SilenceUsage: true, - Args: cobra.NoArgs, - RunE: func(*cobra.Command, []string) error { - return doc.GenMarkdownTree(cli.New(), dir) - }, - } - root.Flags().StringVarP(&dir, "dir", "d", "doc", "Path to directory in which to generate docs") - if err := root.Execute(); err != nil { - fmt.Println(err) - os.Exit(1) - } -} diff --git a/cmd/help/verify.sh b/cmd/help/verify.sh deleted file mode 100755 index 9cdda69ce..000000000 --- a/cmd/help/verify.sh +++ /dev/null @@ -1,25 +0,0 @@ -#!/usr/bin/env bash - -# Copyright 2021 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. - -set -e - -# Verify that generated Markdown docs are up-to-date. -tmpdir=$(mktemp -d) -go run -tags pivkey,pkcs11key,cgo cmd/help/main.go --dir "$tmpdir" -echo "###########################################" -echo "If diffs are found, run: make docgen" -echo "###########################################" -diff -Naur "$tmpdir" doc/ diff --git a/cmd/schema/main.go b/cmd/schema/main.go index 8fec65291..05ced8407 100644 --- a/cmd/schema/main.go +++ b/cmd/schema/main.go @@ -21,11 +21,13 @@ import ( "knative.dev/hack/schema/registry" v1alpha1 "github.com/sigstore/policy-controller/pkg/apis/policy/v1alpha1" + v1beta1 "github.com/sigstore/policy-controller/pkg/apis/policy/v1beta1" ) -// schema is a tool to dump the schema for Eventing resources. +// schema is a tool to dump the schema for policy-controller resources. func main() { registry.Register(&v1alpha1.ClusterImagePolicy{}) + registry.Register(&v1beta1.ClusterImagePolicy{}) if err := commands.New("github.com/sigstore/policy-controller").Execute(); err != nil { log.Fatal("Error during command execution: ", err) diff --git a/cmd/sget/cli/commands.go b/cmd/sget/cli/commands.go deleted file mode 100644 index 9c842e8ef..000000000 --- a/cmd/sget/cli/commands.go +++ /dev/null @@ -1,84 +0,0 @@ -// -// Copyright 2021 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 cli - -import ( - "bytes" - "errors" - "io" - "os" - - "github.com/spf13/cobra" - "sigs.k8s.io/release-utils/version" - - "github.com/sigstore/policy-controller/cmd/sget/cli/options" - "github.com/sigstore/policy-controller/pkg/sget" -) - -var ( - ro = &options.RootOptions{} -) - -func New() *cobra.Command { - cmd := &cobra.Command{ - Use: "sget ", - Short: "sget [--key ] ", - Args: func(cmd *cobra.Command, args []string) error { - if len(args) != 1 { - return errors.New("a single image reference is required") - } - ro.ImageRef = args[0] - return nil - }, - RunE: func(cmd *cobra.Command, args []string) error { - wc, err := createSink(ro.OutputFile) - if err != nil { - return err - } - defer wc.Close() - return sget.New(ro.ImageRef, ro.PublicKey, wc).Do(cmd.Context()) - }, - } - ro.AddFlags(cmd) - - // Add sub-commands. - cmd.AddCommand(version.Version()) - - return cmd -} - -func createSink(path string) (io.WriteCloser, error) { - if path == "" { - // When writing to stdout, buffer so we can check the digest first. - return &buffered{w: os.Stdout, buf: &bytes.Buffer{}}, nil - } - - return os.Create(path) -} - -type buffered struct { - w io.Writer - buf *bytes.Buffer -} - -func (b *buffered) Write(p []byte) (n int, err error) { - return b.buf.Write(p) -} - -func (b *buffered) Close() error { - _, err := io.Copy(b.w, b.buf) - return err -} diff --git a/cmd/sget/cli/options/root.go b/cmd/sget/cli/options/root.go deleted file mode 100644 index e6ae72ae4..000000000 --- a/cmd/sget/cli/options/root.go +++ /dev/null @@ -1,39 +0,0 @@ -// -// Copyright 2021 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 options - -import ( - "github.com/sigstore/policy-controller/cmd/cosign/cli/options" - "github.com/spf13/cobra" -) - -// RootOptions define flags and options for the root sget cli. -type RootOptions struct { - OutputFile string - PublicKey string - ImageRef string -} - -var _ options.Interface = (*RootOptions)(nil) - -// AddFlags implements options.Interface -func (o *RootOptions) AddFlags(cmd *cobra.Command) { - cmd.Flags().StringVarP(&o.OutputFile, "output", "o", "", - "output file") - - cmd.Flags().StringVar(&o.PublicKey, "key", "", - "path to the public key file, URL, or KMS URI") -} diff --git a/cmd/sget/main.go b/cmd/sget/main.go deleted file mode 100644 index 546746859..000000000 --- a/cmd/sget/main.go +++ /dev/null @@ -1,55 +0,0 @@ -// -// Copyright 2021 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 main - -import ( - "fmt" - "log" - "os" - "strings" - - "github.com/sigstore/policy-controller/cmd/sget/cli" - - // Register the provider-specific plugins - _ "github.com/sigstore/sigstore/pkg/signature/kms/aws" - _ "github.com/sigstore/sigstore/pkg/signature/kms/azure" - _ "github.com/sigstore/sigstore/pkg/signature/kms/gcp" - _ "github.com/sigstore/sigstore/pkg/signature/kms/hashivault" -) - -func main() { - // Fix up flags to POSIX standard flags. - for i, arg := range os.Args { - if (strings.HasPrefix(arg, "-") && len(arg) == 2) || (strings.HasPrefix(arg, "--") && len(arg) >= 4) { - continue - } - if strings.HasPrefix(arg, "--") && len(arg) == 3 { - // Handle --o, convert to -o - newArg := fmt.Sprintf("-%c", arg[2]) - fmt.Fprintf(os.Stderr, "WARNING: the flag %s is deprecated and will be removed in a future release. Please use the flag %s.\n", arg, newArg) - os.Args[i] = newArg - } else if strings.HasPrefix(arg, "-") { - // Handle -output, convert to --output - newArg := fmt.Sprintf("-%s", arg) - fmt.Fprintf(os.Stderr, "WARNING: the flag %s is deprecated and will be removed in a future release. Please use the flag %s.\n", arg, newArg) - os.Args[i] = newArg - } - } - - if err := cli.New().Execute(); err != nil { - log.Fatalf("error during command execution: %v", err) - } -} diff --git a/doc/cosign.md b/doc/cosign.md deleted file mode 100644 index 7b214a513..000000000 --- a/doc/cosign.md +++ /dev/null @@ -1,45 +0,0 @@ -## cosign - -A tool for Container Signing, Verification and Storage in an OCI registry. - -### Options - -``` - -h, --help help for cosign - --output-file string log output to a file - -t, --timeout duration timeout for commands (default 3m0s) - -d, --verbose log debug output - -y, --yes skip confirmation prompts for non-destructive operations -``` - -### SEE ALSO - -* [cosign attach](cosign_attach.md) - Provides utilities for attaching artifacts to other artifacts in a registry -* [cosign attest](cosign_attest.md) - Attest the supplied container image. -* [cosign clean](cosign_clean.md) - Remove all signatures from an image. -* [cosign completion](cosign_completion.md) - Generate completion script -* [cosign copy](cosign_copy.md) - Copy the supplied container image and signatures. -* [cosign dockerfile](cosign_dockerfile.md) - Provides utilities for discovering images in and performing operations on Dockerfiles -* [cosign download](cosign_download.md) - Provides utilities for downloading artifacts and attached artifacts in a registry -* [cosign generate](cosign_generate.md) - Generates (unsigned) signature payloads from the supplied container image. -* [cosign generate-key-pair](cosign_generate-key-pair.md) - Generates a key-pair. -* [cosign import-key-pair](cosign_import-key-pair.md) - Imports a PEM-encoded RSA or EC private key. -* [cosign initialize](cosign_initialize.md) - Initializes SigStore root to retrieve trusted certificate and key targets for verification. -* [cosign load](cosign_load.md) - Load a signed image on disk to a remote registry -* [cosign login](cosign_login.md) - Log in to a registry -* [cosign manifest](cosign_manifest.md) - Provides utilities for discovering images in and performing operations on Kubernetes manifests -* [cosign piv-tool](cosign_piv-tool.md) - Provides utilities for managing a hardware token -* [cosign pkcs11-tool](cosign_pkcs11-tool.md) - Provides utilities for retrieving information from a PKCS11 token. -* [cosign policy](cosign_policy.md) - subcommand to manage a keyless policy. -* [cosign public-key](cosign_public-key.md) - Gets a public key from the key-pair. -* [cosign save](cosign_save.md) - Save the container image and associated signatures to disk at the specified directory. -* [cosign sign](cosign_sign.md) - Sign the supplied container image. -* [cosign sign-blob](cosign_sign-blob.md) - Sign the supplied blob, outputting the base64-encoded signature to stdout. -* [cosign tree](cosign_tree.md) - Display supply chain security related artifacts for an image such as signatures, SBOMs and attestations -* [cosign triangulate](cosign_triangulate.md) - Outputs the located cosign image reference. This is the location cosign stores the specified artifact type. -* [cosign upload](cosign_upload.md) - Provides utilities for uploading artifacts to a registry -* [cosign verify](cosign_verify.md) - Verify a signature on the supplied container image -* [cosign verify-attestation](cosign_verify-attestation.md) - Verify an attestation on the supplied container image -* [cosign verify-blob](cosign_verify-blob.md) - Verify a signature on the supplied blob -* [cosign version](cosign_version.md) - Prints the version - diff --git a/doc/cosign_attach.md b/doc/cosign_attach.md deleted file mode 100644 index 03f9b120c..000000000 --- a/doc/cosign_attach.md +++ /dev/null @@ -1,26 +0,0 @@ -## cosign attach - -Provides utilities for attaching artifacts to other artifacts in a registry - -### Options - -``` - -h, --help help for attach -``` - -### Options inherited from parent commands - -``` - --output-file string log output to a file - -t, --timeout duration timeout for commands (default 3m0s) - -d, --verbose log debug output - -y, --yes skip confirmation prompts for non-destructive operations -``` - -### SEE ALSO - -* [cosign](cosign.md) - A tool for Container Signing, Verification and Storage in an OCI registry. -* [cosign attach attestation](cosign_attach_attestation.md) - Attach attestation to the supplied container image -* [cosign attach sbom](cosign_attach_sbom.md) - Attach sbom to the supplied container image -* [cosign attach signature](cosign_attach_signature.md) - Attach signatures to the supplied container image - diff --git a/doc/cosign_attach_attestation.md b/doc/cosign_attach_attestation.md deleted file mode 100644 index 751ef0943..000000000 --- a/doc/cosign_attach_attestation.md +++ /dev/null @@ -1,37 +0,0 @@ -## cosign attach attestation - -Attach attestation to the supplied container image - -``` -cosign attach attestation [flags] -``` - -### Examples - -``` - cosign attach attestation -``` - -### Options - -``` - --allow-insecure-registry whether to allow insecure connections to registries. Don't use this for anything but testing - --attachment-tag-prefix [AttachmentTagPrefix]sha256-[TargetImageDigest].[AttachmentName] optional custom prefix to use for attached image tags. Attachment images are tagged as: [AttachmentTagPrefix]sha256-[TargetImageDigest].[AttachmentName] - --attestation string path to the attestation envelope - -h, --help help for attestation - --k8s-keychain whether to use the kubernetes keychain instead of the default keychain (supports workload identity). -``` - -### Options inherited from parent commands - -``` - --output-file string log output to a file - -t, --timeout duration timeout for commands (default 3m0s) - -d, --verbose log debug output - -y, --yes skip confirmation prompts for non-destructive operations -``` - -### SEE ALSO - -* [cosign attach](cosign_attach.md) - Provides utilities for attaching artifacts to other artifacts in a registry - diff --git a/doc/cosign_attach_sbom.md b/doc/cosign_attach_sbom.md deleted file mode 100644 index 8407f7051..000000000 --- a/doc/cosign_attach_sbom.md +++ /dev/null @@ -1,39 +0,0 @@ -## cosign attach sbom - -Attach sbom to the supplied container image - -``` -cosign attach sbom [flags] -``` - -### Examples - -``` - cosign attach sbom -``` - -### Options - -``` - --allow-insecure-registry whether to allow insecure connections to registries. Don't use this for anything but testing - --attachment-tag-prefix [AttachmentTagPrefix]sha256-[TargetImageDigest].[AttachmentName] optional custom prefix to use for attached image tags. Attachment images are tagged as: [AttachmentTagPrefix]sha256-[TargetImageDigest].[AttachmentName] - -h, --help help for sbom - --input-format string type of sbom input format (json|xml|text) - --k8s-keychain whether to use the kubernetes keychain instead of the default keychain (supports workload identity). - --sbom string path to the sbom, or {-} for stdin - --type string type of sbom (spdx|cyclonedx|syft) (default "spdx") -``` - -### Options inherited from parent commands - -``` - --output-file string log output to a file - -t, --timeout duration timeout for commands (default 3m0s) - -d, --verbose log debug output - -y, --yes skip confirmation prompts for non-destructive operations -``` - -### SEE ALSO - -* [cosign attach](cosign_attach.md) - Provides utilities for attaching artifacts to other artifacts in a registry - diff --git a/doc/cosign_attach_signature.md b/doc/cosign_attach_signature.md deleted file mode 100644 index d55497be3..000000000 --- a/doc/cosign_attach_signature.md +++ /dev/null @@ -1,38 +0,0 @@ -## cosign attach signature - -Attach signatures to the supplied container image - -``` -cosign attach signature [flags] -``` - -### Examples - -``` - cosign attach signature -``` - -### Options - -``` - --allow-insecure-registry whether to allow insecure connections to registries. Don't use this for anything but testing - --attachment-tag-prefix [AttachmentTagPrefix]sha256-[TargetImageDigest].[AttachmentName] optional custom prefix to use for attached image tags. Attachment images are tagged as: [AttachmentTagPrefix]sha256-[TargetImageDigest].[AttachmentName] - -h, --help help for signature - --k8s-keychain whether to use the kubernetes keychain instead of the default keychain (supports workload identity). - --payload string path to the payload covered by the signature (if using another format) - --signature string the signature, path to the signature, or {-} for stdin -``` - -### Options inherited from parent commands - -``` - --output-file string log output to a file - -t, --timeout duration timeout for commands (default 3m0s) - -d, --verbose log debug output - -y, --yes skip confirmation prompts for non-destructive operations -``` - -### SEE ALSO - -* [cosign attach](cosign_attach.md) - Provides utilities for attaching artifacts to other artifacts in a registry - diff --git a/doc/cosign_attest.md b/doc/cosign_attest.md deleted file mode 100644 index 3eb706f27..000000000 --- a/doc/cosign_attest.md +++ /dev/null @@ -1,80 +0,0 @@ -## cosign attest - -Attest the supplied container image. - -``` -cosign attest [flags] -``` - -### Examples - -``` - cosign attest --key | [--predicate ] [--a key=value] [--no-upload=true|false] [--f] [--r] - - # attach an attestation to a container image Google sign-in (experimental) - COSIGN_EXPERIMENTAL=1 cosign attest --timeout 90s --predicate --type - - # attach an attestation to a container image with a local key pair file - cosign attest --predicate --type --key cosign.key - - # attach an attestation to a container image with a key pair stored in Azure Key Vault - cosign attest --predicate --type --key azurekms://[VAULT_NAME][VAULT_URI]/[KEY] - - # attach an attestation to a container image with a key pair stored in AWS KMS - cosign attest --predicate --type --key awskms://[ENDPOINT]/[ID/ALIAS/ARN] - - # attach an attestation to a container image with a key pair stored in Google Cloud KMS - cosign attest --predicate --type --key gcpkms://projects/[PROJECT]/locations/global/keyRings/[KEYRING]/cryptoKeys/[KEY]/versions/[VERSION] - - # attach an attestation to a container image with a key pair stored in Hashicorp Vault - cosign attest --predicate --type --key hashivault://[KEY] - - # attach an attestation to a container image with a local key pair file, including a certificate and certificate chain - cosign attest --predicate --type --key cosign.key --cert cosign.crt --cert-chain chain.crt - - # attach an attestation to a container image which does not fully support OCI media types - COSIGN_DOCKER_MEDIA_TYPES=1 cosign attest --predicate --type --key cosign.key legacy-registry.example.com/my/image -``` - -### Options - -``` - --allow-insecure-registry whether to allow insecure connections to registries. Don't use this for anything but testing - --attachment-tag-prefix [AttachmentTagPrefix]sha256-[TargetImageDigest].[AttachmentName] optional custom prefix to use for attached image tags. Attachment images are tagged as: [AttachmentTagPrefix]sha256-[TargetImageDigest].[AttachmentName] - --certificate string path to the X.509 certificate in PEM format to include in the OCI Signature - --certificate-chain string path to a list of CA X.509 certificates in PEM format which will be needed when building the certificate chain for the signing certificate. Must start with the parent intermediate CA certificate of the signing certificate and end with the root certificate. Included in the OCI Signature - -f, --force skip warnings and confirmations - --fulcio-url string [EXPERIMENTAL] address of sigstore PKI server (default "https://fulcio.sigstore.dev") - -h, --help help for attest - --identity-token string [EXPERIMENTAL] identity token to use for certificate from fulcio - --insecure-skip-verify [EXPERIMENTAL] skip verifying fulcio published to the SCT (this should only be used for testing). - --k8s-keychain whether to use the kubernetes keychain instead of the default keychain (supports workload identity). - --key string path to the private key file, KMS URI or Kubernetes Secret - --no-upload do not upload the generated attestation - --oidc-client-id string [EXPERIMENTAL] OIDC client ID for application (default "sigstore") - --oidc-client-secret-file string [EXPERIMENTAL] Path to file containing OIDC client secret for application - --oidc-disable-ambient-providers [EXPERIMENTAL] Disable ambient OIDC providers. When true, ambient credentials will not be read - --oidc-issuer string [EXPERIMENTAL] OIDC provider to be used to issue ID token (default "https://oauth2.sigstore.dev/auth") - --oidc-redirect-url string [EXPERIMENTAL] OIDC redirect URL (Optional). The default oidc-redirect-url is 'http://localhost:0/auth/callback'. - --predicate string path to the predicate file. - -r, --recursive if a multi-arch image is specified, additionally sign each discrete image - --rekor-url string [EXPERIMENTAL] address of rekor STL server (default "https://rekor.sigstore.dev") - --replace - --sk whether to use a hardware security key - --slot string security key slot to use for generated key (default: signature) (authentication|signature|card-authentication|key-management) - --type string specify a predicate type (slsaprovenance|link|spdx|vuln|custom) or an URI (default "custom") -``` - -### Options inherited from parent commands - -``` - --output-file string log output to a file - -t, --timeout duration timeout for commands (default 3m0s) - -d, --verbose log debug output - -y, --yes skip confirmation prompts for non-destructive operations -``` - -### SEE ALSO - -* [cosign](cosign.md) - A tool for Container Signing, Verification and Storage in an OCI registry. - diff --git a/doc/cosign_clean.md b/doc/cosign_clean.md deleted file mode 100644 index 0fbdfa7a0..000000000 --- a/doc/cosign_clean.md +++ /dev/null @@ -1,38 +0,0 @@ -## cosign clean - -Remove all signatures from an image. - -``` -cosign clean [flags] -``` - -### Examples - -``` - cosign clean -``` - -### Options - -``` - --allow-insecure-registry whether to allow insecure connections to registries. Don't use this for anything but testing - --attachment-tag-prefix [AttachmentTagPrefix]sha256-[TargetImageDigest].[AttachmentName] optional custom prefix to use for attached image tags. Attachment images are tagged as: [AttachmentTagPrefix]sha256-[TargetImageDigest].[AttachmentName] - -f, --force do not prompt for confirmation - -h, --help help for clean - --k8s-keychain whether to use the kubernetes keychain instead of the default keychain (supports workload identity). - --type string a type of clean: (default: all) (default "all") -``` - -### Options inherited from parent commands - -``` - --output-file string log output to a file - -t, --timeout duration timeout for commands (default 3m0s) - -d, --verbose log debug output - -y, --yes skip confirmation prompts for non-destructive operations -``` - -### SEE ALSO - -* [cosign](cosign.md) - A tool for Container Signing, Verification and Storage in an OCI registry. - diff --git a/doc/cosign_completion.md b/doc/cosign_completion.md deleted file mode 100644 index d255ed55f..000000000 --- a/doc/cosign_completion.md +++ /dev/null @@ -1,55 +0,0 @@ -## cosign completion - -Generate completion script - -### Synopsis - -To load completions: -Bash: - $ source <(cosign completion bash) - # To load completions for each session, execute once: - # Linux: - $ cosign completion bash > /etc/bash_completion.d/cosign - # macOS: - $ cosign completion bash > /usr/local/etc/bash_completion.d/cosign -Zsh: - # If shell completion is not already enabled in your environment, - # you will need to enable it. You can execute the following once: - $ echo "autoload -U compinit; compinit" >> ~/.zshrc - # To load completions for each session, execute once: - $ cosign completion zsh > "${fpath[1]}/_cosign" - # You will need to start a new shell for this setup to take effect. -fish: - $ cosign completion fish | source - # To load completions for each session, execute once: - $ cosign completion fish > ~/.config/fish/completions/cosign.fish -PowerShell: - PS> cosign completion powershell | Out-String | Invoke-Expression - # To load completions for every new session, run: - PS> cosign completion powershell > cosign.ps1 - # and source this file from your PowerShell profile. - - -``` -cosign completion [bash|zsh|fish|powershell] -``` - -### Options - -``` - -h, --help help for completion -``` - -### Options inherited from parent commands - -``` - --output-file string log output to a file - -t, --timeout duration timeout for commands (default 3m0s) - -d, --verbose log debug output - -y, --yes skip confirmation prompts for non-destructive operations -``` - -### SEE ALSO - -* [cosign](cosign.md) - A tool for Container Signing, Verification and Storage in an OCI registry. - diff --git a/doc/cosign_copy.md b/doc/cosign_copy.md deleted file mode 100644 index 30de596ac..000000000 --- a/doc/cosign_copy.md +++ /dev/null @@ -1,47 +0,0 @@ -## cosign copy - -Copy the supplied container image and signatures. - -``` -cosign copy [flags] -``` - -### Examples - -``` - cosign copy - - # copy a container image and its signatures - cosign copy example.com/src:latest example.com/dest:latest - - # copy the signatures only - cosign copy --sig-only example.com/src example.com/dest - - # overwrite destination image and signatures - cosign copy -f example.com/src example.com/dest -``` - -### Options - -``` - --allow-insecure-registry whether to allow insecure connections to registries. Don't use this for anything but testing - --attachment-tag-prefix [AttachmentTagPrefix]sha256-[TargetImageDigest].[AttachmentName] optional custom prefix to use for attached image tags. Attachment images are tagged as: [AttachmentTagPrefix]sha256-[TargetImageDigest].[AttachmentName] - -f, --force overwrite destination image(s), if necessary - -h, --help help for copy - --k8s-keychain whether to use the kubernetes keychain instead of the default keychain (supports workload identity). - --sig-only only copy the image signature -``` - -### Options inherited from parent commands - -``` - --output-file string log output to a file - -t, --timeout duration timeout for commands (default 3m0s) - -d, --verbose log debug output - -y, --yes skip confirmation prompts for non-destructive operations -``` - -### SEE ALSO - -* [cosign](cosign.md) - A tool for Container Signing, Verification and Storage in an OCI registry. - diff --git a/doc/cosign_dockerfile.md b/doc/cosign_dockerfile.md deleted file mode 100644 index 0275fca38..000000000 --- a/doc/cosign_dockerfile.md +++ /dev/null @@ -1,24 +0,0 @@ -## cosign dockerfile - -Provides utilities for discovering images in and performing operations on Dockerfiles - -### Options - -``` - -h, --help help for dockerfile -``` - -### Options inherited from parent commands - -``` - --output-file string log output to a file - -t, --timeout duration timeout for commands (default 3m0s) - -d, --verbose log debug output - -y, --yes skip confirmation prompts for non-destructive operations -``` - -### SEE ALSO - -* [cosign](cosign.md) - A tool for Container Signing, Verification and Storage in an OCI registry. -* [cosign dockerfile verify](cosign_dockerfile_verify.md) - Verify a signature on the base image specified in the Dockerfile - diff --git a/doc/cosign_dockerfile_verify.md b/doc/cosign_dockerfile_verify.md deleted file mode 100644 index 97d17aad5..000000000 --- a/doc/cosign_dockerfile_verify.md +++ /dev/null @@ -1,90 +0,0 @@ -## cosign dockerfile verify - -Verify a signature on the base image specified in the Dockerfile - -### Synopsis - -Verify signature and annotations on images in a Dockerfile by checking claims -against the transparency log. - -Shell-like variables in the Dockerfile's FROM lines will be substituted with values from the OS ENV. - -``` -cosign dockerfile verify [flags] -``` - -### Examples - -``` - cosign dockerfile verify --key || - - # verify cosign claims and signing certificates on the FROM images in the Dockerfile - cosign dockerfile verify - - # only verify the base image (the last FROM image) - cosign dockerfile verify --base-image-only - - # additionally verify specified annotations - cosign dockerfile verify -a key1=val1 -a key2=val2 - - # (experimental) additionally, verify with the transparency log - COSIGN_EXPERIMENTAL=1 cosign dockerfile verify - - # verify images with public key - cosign dockerfile verify --key cosign.pub - - # verify images with public key provided by URL - cosign dockerfile verify --key https://host.for/ - - # verify images with public key stored in Azure Key Vault - cosign dockerfile verify --key azurekms://[VAULT_NAME][VAULT_URI]/[KEY] - - # verify images with public key stored in AWS KMS - cosign dockerfile verify --key awskms://[ENDPOINT]/[ID/ALIAS/ARN] - - # verify images with public key stored in Google Cloud KMS - cosign dockerfile verify --key gcpkms://projects/[PROJECT]/locations/global/keyRings/[KEYRING]/cryptoKeys/[KEY] - - # verify images with public key stored in Hashicorp Vault - cosign dockerfile verify --key hashivault://[KEY] -``` - -### Options - -``` - --allow-insecure-registry whether to allow insecure connections to registries. Don't use this for anything but testing - -a, --annotations strings extra key=value pairs to sign - --attachment string related image attachment to sign (sbom), default none - --attachment-tag-prefix [AttachmentTagPrefix]sha256-[TargetImageDigest].[AttachmentName] optional custom prefix to use for attached image tags. Attachment images are tagged as: [AttachmentTagPrefix]sha256-[TargetImageDigest].[AttachmentName] - --base-image-only only verify the base image (the last FROM image in the Dockerfile) - --certificate string path to the public certificate - --certificate-chain string path to a list of CA certificates in PEM format which will be needed when building the certificate chain for the signing certificate. Must start with the parent intermediate CA certificate of the signing certificate and end with the root certificate - --certificate-email string the email expected in a valid Fulcio certificate - --certificate-oidc-issuer string the OIDC issuer expected in a valid Fulcio certificate, e.g. https://token.actions.githubusercontent.com or https://oauth2.sigstore.dev/auth - --check-claims whether to check the claims found (default true) - --enforce-sct whether to enforce that a certificate contain an embedded SCT, a proof of inclusion in a certificate transparency log - -h, --help help for verify - --k8s-keychain whether to use the kubernetes keychain instead of the default keychain (supports workload identity). - --key string path to the public key file, KMS URI or Kubernetes Secret - --local-image whether the specified image is a path to an image saved locally via 'cosign save' - -o, --output string output format for the signing image information (json|text) (default "json") - --rekor-url string [EXPERIMENTAL] address of rekor STL server (default "https://rekor.sigstore.dev") - --signature string signature content or path or remote URL - --signature-digest-algorithm string digest algorithm to use when processing a signature (sha224|sha256|sha384|sha512) (default "sha256") - --sk whether to use a hardware security key - --slot string security key slot to use for generated key (default: signature) (authentication|signature|card-authentication|key-management) -``` - -### Options inherited from parent commands - -``` - --output-file string log output to a file - -t, --timeout duration timeout for commands (default 3m0s) - -d, --verbose log debug output - -y, --yes skip confirmation prompts for non-destructive operations -``` - -### SEE ALSO - -* [cosign dockerfile](cosign_dockerfile.md) - Provides utilities for discovering images in and performing operations on Dockerfiles - diff --git a/doc/cosign_download.md b/doc/cosign_download.md deleted file mode 100644 index eea0b885a..000000000 --- a/doc/cosign_download.md +++ /dev/null @@ -1,26 +0,0 @@ -## cosign download - -Provides utilities for downloading artifacts and attached artifacts in a registry - -### Options - -``` - -h, --help help for download -``` - -### Options inherited from parent commands - -``` - --output-file string log output to a file - -t, --timeout duration timeout for commands (default 3m0s) - -d, --verbose log debug output - -y, --yes skip confirmation prompts for non-destructive operations -``` - -### SEE ALSO - -* [cosign](cosign.md) - A tool for Container Signing, Verification and Storage in an OCI registry. -* [cosign download attestation](cosign_download_attestation.md) - Download in-toto attestations from the supplied container image -* [cosign download sbom](cosign_download_sbom.md) - Download SBOMs from the supplied container image -* [cosign download signature](cosign_download_signature.md) - Download signatures from the supplied container image - diff --git a/doc/cosign_download_attestation.md b/doc/cosign_download_attestation.md deleted file mode 100644 index 81dc60bbb..000000000 --- a/doc/cosign_download_attestation.md +++ /dev/null @@ -1,36 +0,0 @@ -## cosign download attestation - -Download in-toto attestations from the supplied container image - -``` -cosign download attestation [flags] -``` - -### Examples - -``` - cosign download attestation -``` - -### Options - -``` - --allow-insecure-registry whether to allow insecure connections to registries. Don't use this for anything but testing - --attachment-tag-prefix [AttachmentTagPrefix]sha256-[TargetImageDigest].[AttachmentName] optional custom prefix to use for attached image tags. Attachment images are tagged as: [AttachmentTagPrefix]sha256-[TargetImageDigest].[AttachmentName] - -h, --help help for attestation - --k8s-keychain whether to use the kubernetes keychain instead of the default keychain (supports workload identity). -``` - -### Options inherited from parent commands - -``` - --output-file string log output to a file - -t, --timeout duration timeout for commands (default 3m0s) - -d, --verbose log debug output - -y, --yes skip confirmation prompts for non-destructive operations -``` - -### SEE ALSO - -* [cosign download](cosign_download.md) - Provides utilities for downloading artifacts and attached artifacts in a registry - diff --git a/doc/cosign_download_sbom.md b/doc/cosign_download_sbom.md deleted file mode 100644 index bd571cc05..000000000 --- a/doc/cosign_download_sbom.md +++ /dev/null @@ -1,36 +0,0 @@ -## cosign download sbom - -Download SBOMs from the supplied container image - -``` -cosign download sbom [flags] -``` - -### Examples - -``` - cosign download sbom -``` - -### Options - -``` - --allow-insecure-registry whether to allow insecure connections to registries. Don't use this for anything but testing - --attachment-tag-prefix [AttachmentTagPrefix]sha256-[TargetImageDigest].[AttachmentName] optional custom prefix to use for attached image tags. Attachment images are tagged as: [AttachmentTagPrefix]sha256-[TargetImageDigest].[AttachmentName] - -h, --help help for sbom - --k8s-keychain whether to use the kubernetes keychain instead of the default keychain (supports workload identity). -``` - -### Options inherited from parent commands - -``` - --output-file string log output to a file - -t, --timeout duration timeout for commands (default 3m0s) - -d, --verbose log debug output - -y, --yes skip confirmation prompts for non-destructive operations -``` - -### SEE ALSO - -* [cosign download](cosign_download.md) - Provides utilities for downloading artifacts and attached artifacts in a registry - diff --git a/doc/cosign_download_signature.md b/doc/cosign_download_signature.md deleted file mode 100644 index 7071e56f6..000000000 --- a/doc/cosign_download_signature.md +++ /dev/null @@ -1,36 +0,0 @@ -## cosign download signature - -Download signatures from the supplied container image - -``` -cosign download signature [flags] -``` - -### Examples - -``` - cosign download signature -``` - -### Options - -``` - --allow-insecure-registry whether to allow insecure connections to registries. Don't use this for anything but testing - --attachment-tag-prefix [AttachmentTagPrefix]sha256-[TargetImageDigest].[AttachmentName] optional custom prefix to use for attached image tags. Attachment images are tagged as: [AttachmentTagPrefix]sha256-[TargetImageDigest].[AttachmentName] - -h, --help help for signature - --k8s-keychain whether to use the kubernetes keychain instead of the default keychain (supports workload identity). -``` - -### Options inherited from parent commands - -``` - --output-file string log output to a file - -t, --timeout duration timeout for commands (default 3m0s) - -d, --verbose log debug output - -y, --yes skip confirmation prompts for non-destructive operations -``` - -### SEE ALSO - -* [cosign download](cosign_download.md) - Provides utilities for downloading artifacts and attached artifacts in a registry - diff --git a/doc/cosign_generate-key-pair.md b/doc/cosign_generate-key-pair.md deleted file mode 100644 index 07c000cf4..000000000 --- a/doc/cosign_generate-key-pair.md +++ /dev/null @@ -1,69 +0,0 @@ -## cosign generate-key-pair - -Generates a key-pair. - -### Synopsis - -Generates a key-pair for signing. - -``` -cosign generate-key-pair [flags] -``` - -### Examples - -``` - cosign generate-key-pair [--kms KMSPATH] - - # generate key-pair and write to cosign.key and cosign.pub files - cosign generate-key-pair - - # generate a key-pair in Azure Key Vault - cosign generate-key-pair --kms azurekms://[VAULT_NAME][VAULT_URI]/[KEY] - - # generate a key-pair in AWS KMS - cosign generate-key-pair --kms awskms://[ENDPOINT]/[ID/ALIAS/ARN] - - # generate a key-pair in Google Cloud KMS - cosign generate-key-pair --kms gcpkms://projects/[PROJECT]/locations/global/keyRings/[KEYRING]/cryptoKeys/[KEY] - - # generate a key-pair in Hashicorp Vault - cosign generate-key-pair --kms hashivault://[KEY] - - # generate a key-pair in Kubernetes Secret - cosign generate-key-pair k8s://[NAMESPACE]/[NAME] - - # generate a key-pair in GitHub - cosign generate-key-pair github://[OWNER]/[PROJECT_NAME] - - # generate a key-pair in GitLab with project name - cosign generate-key-pair gitlab://[OWNER]/[PROJECT_NAME] - - # generate a key-pair in GitLab with project id - cosign generate-key-pair gitlab://[PROJECT_ID] - -CAVEATS: - This command interactively prompts for a password. You can use - the COSIGN_PASSWORD environment variable to provide one. -``` - -### Options - -``` - -h, --help help for generate-key-pair - --kms string create key pair in KMS service to use for signing -``` - -### Options inherited from parent commands - -``` - --output-file string log output to a file - -t, --timeout duration timeout for commands (default 3m0s) - -d, --verbose log debug output - -y, --yes skip confirmation prompts for non-destructive operations -``` - -### SEE ALSO - -* [cosign](cosign.md) - A tool for Container Signing, Verification and Storage in an OCI registry. - diff --git a/doc/cosign_generate.md b/doc/cosign_generate.md deleted file mode 100644 index 145b1062b..000000000 --- a/doc/cosign_generate.md +++ /dev/null @@ -1,52 +0,0 @@ -## cosign generate - -Generates (unsigned) signature payloads from the supplied container image. - -### Synopsis - -Generates an unsigned payload from the supplied container image and flags. -This payload matches the one generated by the "cosign sign" command and can be used if you need -to sign payloads with your own tooling or algorithms. - -``` -cosign generate [flags] -``` - -### Examples - -``` - cosign generate [--a key=value] - - # Generate a simple payload for an image - cosign generate - - # Generate a payload with specific annotations - cosign generate -a foo=bar - - # Use this payload in another tool - gpg --output image.sig --detach-sig <(cosign generate ) -``` - -### Options - -``` - --allow-insecure-registry whether to allow insecure connections to registries. Don't use this for anything but testing - -a, --annotations strings extra key=value pairs to sign - --attachment-tag-prefix [AttachmentTagPrefix]sha256-[TargetImageDigest].[AttachmentName] optional custom prefix to use for attached image tags. Attachment images are tagged as: [AttachmentTagPrefix]sha256-[TargetImageDigest].[AttachmentName] - -h, --help help for generate - --k8s-keychain whether to use the kubernetes keychain instead of the default keychain (supports workload identity). -``` - -### Options inherited from parent commands - -``` - --output-file string log output to a file - -t, --timeout duration timeout for commands (default 3m0s) - -d, --verbose log debug output - -y, --yes skip confirmation prompts for non-destructive operations -``` - -### SEE ALSO - -* [cosign](cosign.md) - A tool for Container Signing, Verification and Storage in an OCI registry. - diff --git a/doc/cosign_import-key-pair.md b/doc/cosign_import-key-pair.md deleted file mode 100644 index cc67f996f..000000000 --- a/doc/cosign_import-key-pair.md +++ /dev/null @@ -1,45 +0,0 @@ -## cosign import-key-pair - -Imports a PEM-encoded RSA or EC private key. - -### Synopsis - -Imports a PEM-encoded RSA or EC private key for signing. - -``` -cosign import-key-pair [flags] -``` - -### Examples - -``` - cosign import-key-pair --key openssl.key - - # import PEM-encoded RSA or EC private key and write to import-cosign.key and import-cosign.pub files - cosign import-key-pair --key - -CAVEATS: - This command interactively prompts for a password. You can use - the COSIGN_PASSWORD environment variable to provide one. -``` - -### Options - -``` - -h, --help help for import-key-pair - --key string import key pair to use for signing -``` - -### Options inherited from parent commands - -``` - --output-file string log output to a file - -t, --timeout duration timeout for commands (default 3m0s) - -d, --verbose log debug output - -y, --yes skip confirmation prompts for non-destructive operations -``` - -### SEE ALSO - -* [cosign](cosign.md) - A tool for Container Signing, Verification and Storage in an OCI registry. - diff --git a/doc/cosign_initialize.md b/doc/cosign_initialize.md deleted file mode 100644 index 0883071f3..000000000 --- a/doc/cosign_initialize.md +++ /dev/null @@ -1,60 +0,0 @@ -## cosign initialize - -Initializes SigStore root to retrieve trusted certificate and key targets for verification. - -### Synopsis - -Initializes SigStore root to retrieve trusted certificate and key targets for verification. - -The following options are used by default: - - The current trusted Sigstore TUF root is embedded inside cosign at the time of release. - - SigStore remote TUF repository is pulled from the GCS mirror at sigstore-tuf-root. - -To provide an out-of-band trusted initial root.json, use the -root flag with a file or URL reference. -This will enable you to point cosign to a separate TUF root. - -Any updated TUF repository will be written to $HOME/.sigstore/root/. - -Trusted keys and certificate used in cosign verification (e.g. verifying Fulcio issued certificates -with Fulcio root CA) are pulled form the trusted metadata. - -``` -cosign initialize [flags] -``` - -### Examples - -``` -cosign initialize -mirror -out - -# initialize root with distributed root keys, default mirror, and default out path. -cosign initialize - -# initialize with an out-of-band root key file, using the default mirror. -cosign initialize -root - -# initialize with an out-of-band root key file and custom repository mirror. -cosign initialize -mirror -root -``` - -### Options - -``` - -h, --help help for initialize - --mirror string GCS bucket to a SigStore TUF repository or HTTP(S) base URL (default "https://sigstore-tuf-root.storage.googleapis.com") - --root string path to trusted initial root. defaults to embedded root -``` - -### Options inherited from parent commands - -``` - --output-file string log output to a file - -t, --timeout duration timeout for commands (default 3m0s) - -d, --verbose log debug output - -y, --yes skip confirmation prompts for non-destructive operations -``` - -### SEE ALSO - -* [cosign](cosign.md) - A tool for Container Signing, Verification and Storage in an OCI registry. - diff --git a/doc/cosign_load.md b/doc/cosign_load.md deleted file mode 100644 index 42461f88d..000000000 --- a/doc/cosign_load.md +++ /dev/null @@ -1,38 +0,0 @@ -## cosign load - -Load a signed image on disk to a remote registry - -### Synopsis - -Load a signed image on disk to a remote registry - -``` -cosign load [flags] -``` - -### Examples - -``` - cosign load --dir -``` - -### Options - -``` - --dir string path to directory where the signed image is stored on disk - -h, --help help for load -``` - -### Options inherited from parent commands - -``` - --output-file string log output to a file - -t, --timeout duration timeout for commands (default 3m0s) - -d, --verbose log debug output - -y, --yes skip confirmation prompts for non-destructive operations -``` - -### SEE ALSO - -* [cosign](cosign.md) - A tool for Container Signing, Verification and Storage in an OCI registry. - diff --git a/doc/cosign_login.md b/doc/cosign_login.md deleted file mode 100644 index c102cab2c..000000000 --- a/doc/cosign_login.md +++ /dev/null @@ -1,37 +0,0 @@ -## cosign login - -Log in to a registry - -``` -cosign login [OPTIONS] [SERVER] [flags] -``` - -### Examples - -``` - # Log in to reg.example.com - cosign login reg.example.com -u AzureDiamond -p hunter2 -``` - -### Options - -``` - -h, --help help for login - -p, --password string Password - --password-stdin Take the password from stdin - -u, --username string Username -``` - -### Options inherited from parent commands - -``` - --output-file string log output to a file - -t, --timeout duration timeout for commands (default 3m0s) - -d, --verbose log debug output - -y, --yes skip confirmation prompts for non-destructive operations -``` - -### SEE ALSO - -* [cosign](cosign.md) - A tool for Container Signing, Verification and Storage in an OCI registry. - diff --git a/doc/cosign_manifest.md b/doc/cosign_manifest.md deleted file mode 100644 index 1f231bc6d..000000000 --- a/doc/cosign_manifest.md +++ /dev/null @@ -1,24 +0,0 @@ -## cosign manifest - -Provides utilities for discovering images in and performing operations on Kubernetes manifests - -### Options - -``` - -h, --help help for manifest -``` - -### Options inherited from parent commands - -``` - --output-file string log output to a file - -t, --timeout duration timeout for commands (default 3m0s) - -d, --verbose log debug output - -y, --yes skip confirmation prompts for non-destructive operations -``` - -### SEE ALSO - -* [cosign](cosign.md) - A tool for Container Signing, Verification and Storage in an OCI registry. -* [cosign manifest verify](cosign_manifest_verify.md) - Verify all signatures of images specified in the manifest - diff --git a/doc/cosign_manifest_verify.md b/doc/cosign_manifest_verify.md deleted file mode 100644 index b98168ffe..000000000 --- a/doc/cosign_manifest_verify.md +++ /dev/null @@ -1,84 +0,0 @@ -## cosign manifest verify - -Verify all signatures of images specified in the manifest - -### Synopsis - -Verify all signature of images in a Kubernetes resource manifest by checking claims -against the transparency log. - -``` -cosign manifest verify [flags] -``` - -### Examples - -``` - cosign manifest verify --key || - - # verify cosign claims and signing certificates on images in the manifest - cosign manifest verify - - # additionally verify specified annotations - cosign manifest verify -a key1=val1 -a key2=val2 - - # (experimental) additionally, verify with the transparency log - COSIGN_EXPERIMENTAL=1 cosign manifest verify - - # verify images with public key - cosign manifest verify --key cosign.pub - - # verify images with public key provided by URL - cosign manifest verify --key https://host.for/ - - # verify images with public key stored in Azure Key Vault - cosign manifest verify --key azurekms://[VAULT_NAME][VAULT_URI]/[KEY] - - # verify images with public key stored in AWS KMS - cosign manifest verify --key awskms://[ENDPOINT]/[ID/ALIAS/ARN] - - # verify images with public key stored in Google Cloud KMS - cosign manifest verify --key gcpkms://projects/[PROJECT]/locations/global/keyRings/[KEYRING]/cryptoKeys/[KEY] - - # verify images with public key stored in Hashicorp Vault - cosign manifest verify --key hashivault://[KEY] -``` - -### Options - -``` - --allow-insecure-registry whether to allow insecure connections to registries. Don't use this for anything but testing - -a, --annotations strings extra key=value pairs to sign - --attachment string related image attachment to sign (sbom), default none - --attachment-tag-prefix [AttachmentTagPrefix]sha256-[TargetImageDigest].[AttachmentName] optional custom prefix to use for attached image tags. Attachment images are tagged as: [AttachmentTagPrefix]sha256-[TargetImageDigest].[AttachmentName] - --certificate string path to the public certificate - --certificate-chain string path to a list of CA certificates in PEM format which will be needed when building the certificate chain for the signing certificate. Must start with the parent intermediate CA certificate of the signing certificate and end with the root certificate - --certificate-email string the email expected in a valid Fulcio certificate - --certificate-oidc-issuer string the OIDC issuer expected in a valid Fulcio certificate, e.g. https://token.actions.githubusercontent.com or https://oauth2.sigstore.dev/auth - --check-claims whether to check the claims found (default true) - --enforce-sct whether to enforce that a certificate contain an embedded SCT, a proof of inclusion in a certificate transparency log - -h, --help help for verify - --k8s-keychain whether to use the kubernetes keychain instead of the default keychain (supports workload identity). - --key string path to the public key file, KMS URI or Kubernetes Secret - --local-image whether the specified image is a path to an image saved locally via 'cosign save' - -o, --output string output format for the signing image information (json|text) (default "json") - --rekor-url string [EXPERIMENTAL] address of rekor STL server (default "https://rekor.sigstore.dev") - --signature string signature content or path or remote URL - --signature-digest-algorithm string digest algorithm to use when processing a signature (sha224|sha256|sha384|sha512) (default "sha256") - --sk whether to use a hardware security key - --slot string security key slot to use for generated key (default: signature) (authentication|signature|card-authentication|key-management) -``` - -### Options inherited from parent commands - -``` - --output-file string log output to a file - -t, --timeout duration timeout for commands (default 3m0s) - -d, --verbose log debug output - -y, --yes skip confirmation prompts for non-destructive operations -``` - -### SEE ALSO - -* [cosign manifest](cosign_manifest.md) - Provides utilities for discovering images in and performing operations on Kubernetes manifests - diff --git a/doc/cosign_piv-tool.md b/doc/cosign_piv-tool.md deleted file mode 100644 index ebecea4a6..000000000 --- a/doc/cosign_piv-tool.md +++ /dev/null @@ -1,31 +0,0 @@ -## cosign piv-tool - -Provides utilities for managing a hardware token - -### Options - -``` - -h, --help help for piv-tool - -f, --no-input skip warnings and confirmations -``` - -### Options inherited from parent commands - -``` - --output-file string log output to a file - -t, --timeout duration timeout for commands (default 3m0s) - -d, --verbose log debug output - -y, --yes skip confirmation prompts for non-destructive operations -``` - -### SEE ALSO - -* [cosign](cosign.md) - A tool for Container Signing, Verification and Storage in an OCI registry. -* [cosign piv-tool attestation](cosign_piv-tool_attestation.md) - attestation contains commands to manage a hardware token -* [cosign piv-tool generate-key](cosign_piv-tool_generate-key.md) - generate-key generates a new signing key on the hardware token -* [cosign piv-tool reset](cosign_piv-tool_reset.md) - reset resets the hardware token completely -* [cosign piv-tool set-management-key](cosign_piv-tool_set-management-key.md) - sets the management key of a hardware token -* [cosign piv-tool set-pin](cosign_piv-tool_set-pin.md) - sets the PIN on a hardware token -* [cosign piv-tool set-puk](cosign_piv-tool_set-puk.md) - sets the PUK on a hardware token -* [cosign piv-tool unblock](cosign_piv-tool_unblock.md) - unblocks the hardware token, sets a new PIN - diff --git a/doc/cosign_piv-tool_attestation.md b/doc/cosign_piv-tool_attestation.md deleted file mode 100644 index f9895598d..000000000 --- a/doc/cosign_piv-tool_attestation.md +++ /dev/null @@ -1,30 +0,0 @@ -## cosign piv-tool attestation - -attestation contains commands to manage a hardware token - -``` -cosign piv-tool attestation [flags] -``` - -### Options - -``` - -h, --help help for attestation - -o, --output string format to output attestation information in. (text|json) (default "text") - --slot string Slot to use for generated key (authentication|signature|card-authentication|key-management) -``` - -### Options inherited from parent commands - -``` - -f, --no-input skip warnings and confirmations - --output-file string log output to a file - -t, --timeout duration timeout for commands (default 3m0s) - -d, --verbose log debug output - -y, --yes skip confirmation prompts for non-destructive operations -``` - -### SEE ALSO - -* [cosign piv-tool](cosign_piv-tool.md) - Provides utilities for managing a hardware token - diff --git a/doc/cosign_piv-tool_generate-key.md b/doc/cosign_piv-tool_generate-key.md deleted file mode 100644 index 5097e1fb4..000000000 --- a/doc/cosign_piv-tool_generate-key.md +++ /dev/null @@ -1,33 +0,0 @@ -## cosign piv-tool generate-key - -generate-key generates a new signing key on the hardware token - -``` -cosign piv-tool generate-key [flags] -``` - -### Options - -``` - -h, --help help for generate-key - --management-key string management key, uses default if empty - --pin-policy string PIN policy for slot (never|once|always) - --random-management-key if set to true, generates a new random management key and deletes it after - --slot string Slot to use for generated key (authentication|signature|card-authentication|key-management) - --touch-policy string Touch policy for slot (never|always|cached) -``` - -### Options inherited from parent commands - -``` - -f, --no-input skip warnings and confirmations - --output-file string log output to a file - -t, --timeout duration timeout for commands (default 3m0s) - -d, --verbose log debug output - -y, --yes skip confirmation prompts for non-destructive operations -``` - -### SEE ALSO - -* [cosign piv-tool](cosign_piv-tool.md) - Provides utilities for managing a hardware token - diff --git a/doc/cosign_piv-tool_reset.md b/doc/cosign_piv-tool_reset.md deleted file mode 100644 index bba7a5afd..000000000 --- a/doc/cosign_piv-tool_reset.md +++ /dev/null @@ -1,28 +0,0 @@ -## cosign piv-tool reset - -reset resets the hardware token completely - -``` -cosign piv-tool reset [flags] -``` - -### Options - -``` - -h, --help help for reset -``` - -### Options inherited from parent commands - -``` - -f, --no-input skip warnings and confirmations - --output-file string log output to a file - -t, --timeout duration timeout for commands (default 3m0s) - -d, --verbose log debug output - -y, --yes skip confirmation prompts for non-destructive operations -``` - -### SEE ALSO - -* [cosign piv-tool](cosign_piv-tool.md) - Provides utilities for managing a hardware token - diff --git a/doc/cosign_piv-tool_set-management-key.md b/doc/cosign_piv-tool_set-management-key.md deleted file mode 100644 index d55d2c841..000000000 --- a/doc/cosign_piv-tool_set-management-key.md +++ /dev/null @@ -1,31 +0,0 @@ -## cosign piv-tool set-management-key - -sets the management key of a hardware token - -``` -cosign piv-tool set-management-key [flags] -``` - -### Options - -``` - -h, --help help for set-management-key - --new-key string new management key, uses default if empty - --old-key string existing management key, uses default if empty - --random-management-key if set to true, generates a new random management key and deletes it after -``` - -### Options inherited from parent commands - -``` - -f, --no-input skip warnings and confirmations - --output-file string log output to a file - -t, --timeout duration timeout for commands (default 3m0s) - -d, --verbose log debug output - -y, --yes skip confirmation prompts for non-destructive operations -``` - -### SEE ALSO - -* [cosign piv-tool](cosign_piv-tool.md) - Provides utilities for managing a hardware token - diff --git a/doc/cosign_piv-tool_set-pin.md b/doc/cosign_piv-tool_set-pin.md deleted file mode 100644 index e73ce96ea..000000000 --- a/doc/cosign_piv-tool_set-pin.md +++ /dev/null @@ -1,30 +0,0 @@ -## cosign piv-tool set-pin - -sets the PIN on a hardware token - -``` -cosign piv-tool set-pin [flags] -``` - -### Options - -``` - -h, --help help for set-pin - --new-pin string new PIN, uses default if empty - --old-pin string existing PIN, uses default if empty -``` - -### Options inherited from parent commands - -``` - -f, --no-input skip warnings and confirmations - --output-file string log output to a file - -t, --timeout duration timeout for commands (default 3m0s) - -d, --verbose log debug output - -y, --yes skip confirmation prompts for non-destructive operations -``` - -### SEE ALSO - -* [cosign piv-tool](cosign_piv-tool.md) - Provides utilities for managing a hardware token - diff --git a/doc/cosign_piv-tool_set-puk.md b/doc/cosign_piv-tool_set-puk.md deleted file mode 100644 index 34ea39bca..000000000 --- a/doc/cosign_piv-tool_set-puk.md +++ /dev/null @@ -1,30 +0,0 @@ -## cosign piv-tool set-puk - -sets the PUK on a hardware token - -``` -cosign piv-tool set-puk [flags] -``` - -### Options - -``` - -h, --help help for set-puk - --new-puk string new PUK, uses default if empty - --old-puk string existing PUK, uses default if empty -``` - -### Options inherited from parent commands - -``` - -f, --no-input skip warnings and confirmations - --output-file string log output to a file - -t, --timeout duration timeout for commands (default 3m0s) - -d, --verbose log debug output - -y, --yes skip confirmation prompts for non-destructive operations -``` - -### SEE ALSO - -* [cosign piv-tool](cosign_piv-tool.md) - Provides utilities for managing a hardware token - diff --git a/doc/cosign_piv-tool_unblock.md b/doc/cosign_piv-tool_unblock.md deleted file mode 100644 index 4b2767545..000000000 --- a/doc/cosign_piv-tool_unblock.md +++ /dev/null @@ -1,30 +0,0 @@ -## cosign piv-tool unblock - -unblocks the hardware token, sets a new PIN - -``` -cosign piv-tool unblock [flags] -``` - -### Options - -``` - -h, --help help for unblock - --new-PIN string new PIN, uses default if empty - --puk string existing PUK, uses default if empty -``` - -### Options inherited from parent commands - -``` - -f, --no-input skip warnings and confirmations - --output-file string log output to a file - -t, --timeout duration timeout for commands (default 3m0s) - -d, --verbose log debug output - -y, --yes skip confirmation prompts for non-destructive operations -``` - -### SEE ALSO - -* [cosign piv-tool](cosign_piv-tool.md) - Provides utilities for managing a hardware token - diff --git a/doc/cosign_pkcs11-tool.md b/doc/cosign_pkcs11-tool.md deleted file mode 100644 index 9a39d22a3..000000000 --- a/doc/cosign_pkcs11-tool.md +++ /dev/null @@ -1,26 +0,0 @@ -## cosign pkcs11-tool - -Provides utilities for retrieving information from a PKCS11 token. - -### Options - -``` - -h, --help help for pkcs11-tool - -f, --no-input skip warnings and confirmations -``` - -### Options inherited from parent commands - -``` - --output-file string log output to a file - -t, --timeout duration timeout for commands (default 3m0s) - -d, --verbose log debug output - -y, --yes skip confirmation prompts for non-destructive operations -``` - -### SEE ALSO - -* [cosign](cosign.md) - A tool for Container Signing, Verification and Storage in an OCI registry. -* [cosign pkcs11-tool list-keys-uris](cosign_pkcs11-tool_list-keys-uris.md) - list-keys-uris lists URIs of all keys in a PKCS11 token -* [cosign pkcs11-tool list-tokens](cosign_pkcs11-tool_list-tokens.md) - list-tokens lists all PKCS11 tokens linked to a PKCS11 module - diff --git a/doc/cosign_pkcs11-tool_list-keys-uris.md b/doc/cosign_pkcs11-tool_list-keys-uris.md deleted file mode 100644 index 85b9a1e76..000000000 --- a/doc/cosign_pkcs11-tool_list-keys-uris.md +++ /dev/null @@ -1,31 +0,0 @@ -## cosign pkcs11-tool list-keys-uris - -list-keys-uris lists URIs of all keys in a PKCS11 token - -``` -cosign pkcs11-tool list-keys-uris [flags] -``` - -### Options - -``` - -h, --help help for list-keys-uris - --module-path string absolute path to the PKCS11 module - --pin string pin of the PKCS11 slot, uses environment variable COSIGN_PKCS11_PIN if empty - --slot-id uint id of the PKCS11 slot, uses 0 if empty -``` - -### Options inherited from parent commands - -``` - -f, --no-input skip warnings and confirmations - --output-file string log output to a file - -t, --timeout duration timeout for commands (default 3m0s) - -d, --verbose log debug output - -y, --yes skip confirmation prompts for non-destructive operations -``` - -### SEE ALSO - -* [cosign pkcs11-tool](cosign_pkcs11-tool.md) - Provides utilities for retrieving information from a PKCS11 token. - diff --git a/doc/cosign_pkcs11-tool_list-tokens.md b/doc/cosign_pkcs11-tool_list-tokens.md deleted file mode 100644 index 5ba026759..000000000 --- a/doc/cosign_pkcs11-tool_list-tokens.md +++ /dev/null @@ -1,29 +0,0 @@ -## cosign pkcs11-tool list-tokens - -list-tokens lists all PKCS11 tokens linked to a PKCS11 module - -``` -cosign pkcs11-tool list-tokens [flags] -``` - -### Options - -``` - -h, --help help for list-tokens - --module-path string absolute path to the PKCS11 module -``` - -### Options inherited from parent commands - -``` - -f, --no-input skip warnings and confirmations - --output-file string log output to a file - -t, --timeout duration timeout for commands (default 3m0s) - -d, --verbose log debug output - -y, --yes skip confirmation prompts for non-destructive operations -``` - -### SEE ALSO - -* [cosign pkcs11-tool](cosign_pkcs11-tool.md) - Provides utilities for retrieving information from a PKCS11 token. - diff --git a/doc/cosign_policy.md b/doc/cosign_policy.md deleted file mode 100644 index 513cc6ec7..000000000 --- a/doc/cosign_policy.md +++ /dev/null @@ -1,35 +0,0 @@ -## cosign policy - -subcommand to manage a keyless policy. - -### Synopsis - -policy is used to manage a root.json policy -for keyless signing delegation. This is used to establish a policy for a registry namespace, -a signing threshold and a list of maintainers who can sign over the body section. - -``` -cosign policy [flags] -``` - -### Options - -``` - -h, --help help for policy -``` - -### Options inherited from parent commands - -``` - --output-file string log output to a file - -t, --timeout duration timeout for commands (default 3m0s) - -d, --verbose log debug output - -y, --yes skip confirmation prompts for non-destructive operations -``` - -### SEE ALSO - -* [cosign](cosign.md) - A tool for Container Signing, Verification and Storage in an OCI registry. -* [cosign policy init](cosign_policy_init.md) - generate a new keyless policy. -* [cosign policy sign](cosign_policy_sign.md) - sign a keyless policy. - diff --git a/doc/cosign_policy_init.md b/doc/cosign_policy_init.md deleted file mode 100644 index b757ce6cb..000000000 --- a/doc/cosign_policy_init.md +++ /dev/null @@ -1,50 +0,0 @@ -## cosign policy init - -generate a new keyless policy. - -### Synopsis - -init is used to generate a root.json policy -for keyless signing delegation. This is used to establish a policy for a registry namespace, -a signing threshold and a list of maintainers who can sign over the body section. - -``` -cosign policy init [flags] -``` - -### Examples - -``` - - # extract public key from private key to a specified out file. - cosign policy init -ns --maintainers {email_addresses} --threshold --expires (days) -``` - -### Options - -``` - --allow-insecure-registry whether to allow insecure connections to registries. Don't use this for anything but testing - --attachment-tag-prefix [AttachmentTagPrefix]sha256-[TargetImageDigest].[AttachmentName] optional custom prefix to use for attached image tags. Attachment images are tagged as: [AttachmentTagPrefix]sha256-[TargetImageDigest].[AttachmentName] - --expires int total expire duration in days - -h, --help help for init - --issuer string trusted issuer to use for identity tokens, e.g. https://accounts.google.com - --k8s-keychain whether to use the kubernetes keychain instead of the default keychain (supports workload identity). - -m, --maintainers strings list of maintainers to add to the root policy - --namespace string registry namespace that the root policy belongs to (default "ns") - --out string output policy locally (default "o") - --threshold int threshold for root policy signers (default 1) -``` - -### Options inherited from parent commands - -``` - --output-file string log output to a file - -t, --timeout duration timeout for commands (default 3m0s) - -d, --verbose log debug output - -y, --yes skip confirmation prompts for non-destructive operations -``` - -### SEE ALSO - -* [cosign policy](cosign_policy.md) - subcommand to manage a keyless policy. - diff --git a/doc/cosign_policy_sign.md b/doc/cosign_policy_sign.md deleted file mode 100644 index 053b465a3..000000000 --- a/doc/cosign_policy_sign.md +++ /dev/null @@ -1,47 +0,0 @@ -## cosign policy sign - -sign a keyless policy. - -### Synopsis - -policy is used to manage a root.json policy -for keyless signing delegation. This is used to establish a policy for a registry namespace, -a signing threshold and a list of maintainers who can sign over the body section. - -``` -cosign policy sign [flags] -``` - -### Options - -``` - --allow-insecure-registry whether to allow insecure connections to registries. Don't use this for anything but testing - --attachment-tag-prefix [AttachmentTagPrefix]sha256-[TargetImageDigest].[AttachmentName] optional custom prefix to use for attached image tags. Attachment images are tagged as: [AttachmentTagPrefix]sha256-[TargetImageDigest].[AttachmentName] - --fulcio-url string [EXPERIMENTAL] address of sigstore PKI server (default "https://fulcio.sigstore.dev") - -h, --help help for sign - --identity-token string [EXPERIMENTAL] identity token to use for certificate from fulcio - --insecure-skip-verify [EXPERIMENTAL] skip verifying fulcio published to the SCT (this should only be used for testing). - --k8s-keychain whether to use the kubernetes keychain instead of the default keychain (supports workload identity). - --namespace string registry namespace that the root policy belongs to (default "ns") - --oidc-client-id string [EXPERIMENTAL] OIDC client ID for application (default "sigstore") - --oidc-client-secret-file string [EXPERIMENTAL] Path to file containing OIDC client secret for application - --oidc-disable-ambient-providers [EXPERIMENTAL] Disable ambient OIDC providers. When true, ambient credentials will not be read - --oidc-issuer string [EXPERIMENTAL] OIDC provider to be used to issue ID token (default "https://oauth2.sigstore.dev/auth") - --oidc-redirect-url string [EXPERIMENTAL] OIDC redirect URL (Optional). The default oidc-redirect-url is 'http://localhost:0/auth/callback'. - --out string output policy locally (default "o") - --rekor-url string [EXPERIMENTAL] address of rekor STL server (default "https://rekor.sigstore.dev") -``` - -### Options inherited from parent commands - -``` - --output-file string log output to a file - -t, --timeout duration timeout for commands (default 3m0s) - -d, --verbose log debug output - -y, --yes skip confirmation prompts for non-destructive operations -``` - -### SEE ALSO - -* [cosign policy](cosign_policy.md) - subcommand to manage a keyless policy. - diff --git a/doc/cosign_public-key.md b/doc/cosign_public-key.md deleted file mode 100644 index 555fc8052..000000000 --- a/doc/cosign_public-key.md +++ /dev/null @@ -1,65 +0,0 @@ -## cosign public-key - -Gets a public key from the key-pair. - -### Synopsis - -Gets a public key from the key-pair and -writes to a specified file. By default, it will write to standard out. - -``` -cosign public-key [flags] -``` - -### Examples - -``` - - # extract public key from private key to a specified out file. - cosign public-key --key --outfile - - # extract public key from URL. - cosign public-key --key https://host.for/ --outfile - - # extract public key from Azure Key Vault - cosign public-key --key azurekms://[VAULT_NAME][VAULT_URI]/[KEY] - - # extract public key from AWS KMS - cosign public-key --key awskms://[ENDPOINT]/[ID/ALIAS/ARN] - - # extract public key from Google Cloud KMS - cosign public-key --key gcpkms://projects/[PROJECT]/locations/global/keyRings/[KEYRING]/cryptoKeys/[KEY] - - # extract public key from Hashicorp Vault KMS - cosign public-key --key hashivault://[KEY] - - # extract public key from GitLab with project name - cosign verify --key gitlab://[OWNER]/[PROJECT_NAME] - - # extract public key from GitLab with project id - cosign verify --key gitlab://[PROJECT_ID] -``` - -### Options - -``` - -h, --help help for public-key - --key string path to the private key file, KMS URI or Kubernetes Secret - --outfile string path to a payload file to use rather than generating one - --sk whether to use a hardware security key - --slot string security key slot to use for generated key (default: signature) (authentication|signature|card-authentication|key-management) -``` - -### Options inherited from parent commands - -``` - --output-file string log output to a file - -t, --timeout duration timeout for commands (default 3m0s) - -d, --verbose log debug output - -y, --yes skip confirmation prompts for non-destructive operations -``` - -### SEE ALSO - -* [cosign](cosign.md) - A tool for Container Signing, Verification and Storage in an OCI registry. - diff --git a/doc/cosign_save.md b/doc/cosign_save.md deleted file mode 100644 index 1f64f6a45..000000000 --- a/doc/cosign_save.md +++ /dev/null @@ -1,38 +0,0 @@ -## cosign save - -Save the container image and associated signatures to disk at the specified directory. - -### Synopsis - -Save the container image and associated signatures to disk at the specified directory. - -``` -cosign save [flags] -``` - -### Examples - -``` - cosign save --dir -``` - -### Options - -``` - --dir string path to dir where the signed image should be stored on disk - -h, --help help for save -``` - -### Options inherited from parent commands - -``` - --output-file string log output to a file - -t, --timeout duration timeout for commands (default 3m0s) - -d, --verbose log debug output - -y, --yes skip confirmation prompts for non-destructive operations -``` - -### SEE ALSO - -* [cosign](cosign.md) - A tool for Container Signing, Verification and Storage in an OCI registry. - diff --git a/doc/cosign_sign-blob.md b/doc/cosign_sign-blob.md deleted file mode 100644 index 9d98514e8..000000000 --- a/doc/cosign_sign-blob.md +++ /dev/null @@ -1,71 +0,0 @@ -## cosign sign-blob - -Sign the supplied blob, outputting the base64-encoded signature to stdout. - -``` -cosign sign-blob [flags] -``` - -### Examples - -``` - cosign sign-blob --key | - - # sign a blob with Google sign-in (experimental) - COSIGN_EXPERIMENTAL=1 cosign --timeout 90s sign-blob - - # sign a blob with a local key pair file - cosign sign-blob --key cosign.key - - # sign a blob with a key pair stored in Azure Key Vault - cosign sign-blob --key azurekms://[VAULT_NAME][VAULT_URI]/[KEY] - - # sign a blob with a key pair stored in AWS KMS - cosign sign-blob --key awskms://[ENDPOINT]/[ID/ALIAS/ARN] - - # sign a blob with a key pair stored in Google Cloud KMS - cosign sign-blob --key gcpkms://projects/[PROJECT]/locations/global/keyRings/[KEYRING]/cryptoKeys/[KEY] - - # sign a blob with a key pair stored in Hashicorp Vault - cosign sign-blob --key hashivault://[KEY] -``` - -### Options - -``` - --allow-insecure-registry whether to allow insecure connections to registries. Don't use this for anything but testing - --attachment-tag-prefix [AttachmentTagPrefix]sha256-[TargetImageDigest].[AttachmentName] optional custom prefix to use for attached image tags. Attachment images are tagged as: [AttachmentTagPrefix]sha256-[TargetImageDigest].[AttachmentName] - --b64 whether to base64 encode the output (default true) - --bundle string write everything required to verify the blob to a FILE - --fulcio-url string [EXPERIMENTAL] address of sigstore PKI server (default "https://fulcio.sigstore.dev") - -h, --help help for sign-blob - --identity-token string [EXPERIMENTAL] identity token to use for certificate from fulcio - --insecure-skip-verify [EXPERIMENTAL] skip verifying fulcio published to the SCT (this should only be used for testing). - --k8s-keychain whether to use the kubernetes keychain instead of the default keychain (supports workload identity). - --key string path to the private key file, KMS URI or Kubernetes Secret - --oidc-client-id string [EXPERIMENTAL] OIDC client ID for application (default "sigstore") - --oidc-client-secret-file string [EXPERIMENTAL] Path to file containing OIDC client secret for application - --oidc-disable-ambient-providers [EXPERIMENTAL] Disable ambient OIDC providers. When true, ambient credentials will not be read - --oidc-issuer string [EXPERIMENTAL] OIDC provider to be used to issue ID token (default "https://oauth2.sigstore.dev/auth") - --oidc-redirect-url string [EXPERIMENTAL] OIDC redirect URL (Optional). The default oidc-redirect-url is 'http://localhost:0/auth/callback'. - --output string write the signature to FILE - --output-certificate string write the certificate to FILE - --output-signature string write the signature to FILE - --rekor-url string [EXPERIMENTAL] address of rekor STL server (default "https://rekor.sigstore.dev") - --sk whether to use a hardware security key - --slot string security key slot to use for generated key (default: signature) (authentication|signature|card-authentication|key-management) -``` - -### Options inherited from parent commands - -``` - --output-file string log output to a file - -t, --timeout duration timeout for commands (default 3m0s) - -d, --verbose log debug output - -y, --yes skip confirmation prompts for non-destructive operations -``` - -### SEE ALSO - -* [cosign](cosign.md) - A tool for Container Signing, Verification and Storage in an OCI registry. - diff --git a/doc/cosign_sign.md b/doc/cosign_sign.md deleted file mode 100644 index 10ad09ad8..000000000 --- a/doc/cosign_sign.md +++ /dev/null @@ -1,98 +0,0 @@ -## cosign sign - -Sign the supplied container image. - -### Synopsis - -Sign the supplied container image. - -``` -cosign sign [flags] -``` - -### Examples - -``` - cosign sign --key | [--payload ] [-a key=value] [--upload=true|false] [-f] [-r] - - # sign a container image with Google sign-in (experimental) - COSIGN_EXPERIMENTAL=1 cosign sign - - # sign a container image with a local key pair file - cosign sign --key cosign.key - - # sign a multi-arch container image AND all referenced, discrete images - cosign sign --key cosign.key --recursive - - # sign a container image and add annotations - cosign sign --key cosign.key -a key1=value1 -a key2=value2 - - # sign a container image with a key stored in an environment variable - cosign sign --key env://[ENV_VAR] - - # sign a container image with a key pair stored in Azure Key Vault - cosign sign --key azurekms://[VAULT_NAME][VAULT_URI]/[KEY] - - # sign a container image with a key pair stored in AWS KMS - cosign sign --key awskms://[ENDPOINT]/[ID/ALIAS/ARN] - - # sign a container image with a key pair stored in Google Cloud KMS - cosign sign --key gcpkms://projects/[PROJECT]/locations/global/keyRings/[KEYRING]/cryptoKeys/[KEY]/versions/[VERSION] - - # sign a container image with a key pair stored in Hashicorp Vault - cosign sign --key hashivault://[KEY] - - # sign a container image with a key pair stored in a Kubernetes secret - cosign sign --key k8s://[NAMESPACE]/[KEY] - - # sign a container image with a key, attaching a certificate and certificate chain - cosign sign --key cosign.key --cert cosign.crt --cert-chain chain.crt - - # sign a container in a registry which does not fully support OCI media types - COSIGN_DOCKER_MEDIA_TYPES=1 cosign sign --key cosign.key legacy-registry.example.com/my/image -``` - -### Options - -``` - --allow-insecure-registry whether to allow insecure connections to registries. Don't use this for anything but testing - -a, --annotations strings extra key=value pairs to sign - --attachment string related image attachment to sign (sbom), default none - --attachment-tag-prefix [AttachmentTagPrefix]sha256-[TargetImageDigest].[AttachmentName] optional custom prefix to use for attached image tags. Attachment images are tagged as: [AttachmentTagPrefix]sha256-[TargetImageDigest].[AttachmentName] - --certificate string path to the X.509 certificate in PEM format to include in the OCI Signature - --certificate-chain string path to a list of CA X.509 certificates in PEM format which will be needed when building the certificate chain for the signing certificate. Must start with the parent intermediate CA certificate of the signing certificate and end with the root certificate. Included in the OCI Signature - -f, --force skip warnings and confirmations - --fulcio-url string [EXPERIMENTAL] address of sigstore PKI server (default "https://fulcio.sigstore.dev") - -h, --help help for sign - --identity-token string [EXPERIMENTAL] identity token to use for certificate from fulcio - --insecure-skip-verify [EXPERIMENTAL] skip verifying fulcio published to the SCT (this should only be used for testing). - --k8s-keychain whether to use the kubernetes keychain instead of the default keychain (supports workload identity). - --key string path to the private key file, KMS URI or Kubernetes Secret - --oidc-client-id string [EXPERIMENTAL] OIDC client ID for application (default "sigstore") - --oidc-client-secret-file string [EXPERIMENTAL] Path to file containing OIDC client secret for application - --oidc-disable-ambient-providers [EXPERIMENTAL] Disable ambient OIDC providers. When true, ambient credentials will not be read - --oidc-issuer string [EXPERIMENTAL] OIDC provider to be used to issue ID token (default "https://oauth2.sigstore.dev/auth") - --oidc-redirect-url string [EXPERIMENTAL] OIDC redirect URL (Optional). The default oidc-redirect-url is 'http://localhost:0/auth/callback'. - --output-certificate string write the certificate to FILE - --output-signature string write the signature to FILE - --payload string path to a payload file to use rather than generating one - -r, --recursive if a multi-arch image is specified, additionally sign each discrete image - --rekor-url string [EXPERIMENTAL] address of rekor STL server (default "https://rekor.sigstore.dev") - --sk whether to use a hardware security key - --slot string security key slot to use for generated key (default: signature) (authentication|signature|card-authentication|key-management) - --upload whether to upload the signature (default true) -``` - -### Options inherited from parent commands - -``` - --output-file string log output to a file - -t, --timeout duration timeout for commands (default 3m0s) - -d, --verbose log debug output - -y, --yes skip confirmation prompts for non-destructive operations -``` - -### SEE ALSO - -* [cosign](cosign.md) - A tool for Container Signing, Verification and Storage in an OCI registry. - diff --git a/doc/cosign_tree.md b/doc/cosign_tree.md deleted file mode 100644 index 32f3b3a47..000000000 --- a/doc/cosign_tree.md +++ /dev/null @@ -1,36 +0,0 @@ -## cosign tree - -Display supply chain security related artifacts for an image such as signatures, SBOMs and attestations - -``` -cosign tree [flags] -``` - -### Examples - -``` - cosign tree -``` - -### Options - -``` - --allow-insecure-registry whether to allow insecure connections to registries. Don't use this for anything but testing - --attachment-tag-prefix [AttachmentTagPrefix]sha256-[TargetImageDigest].[AttachmentName] optional custom prefix to use for attached image tags. Attachment images are tagged as: [AttachmentTagPrefix]sha256-[TargetImageDigest].[AttachmentName] - -h, --help help for tree - --k8s-keychain whether to use the kubernetes keychain instead of the default keychain (supports workload identity). -``` - -### Options inherited from parent commands - -``` - --output-file string log output to a file - -t, --timeout duration timeout for commands (default 3m0s) - -d, --verbose log debug output - -y, --yes skip confirmation prompts for non-destructive operations -``` - -### SEE ALSO - -* [cosign](cosign.md) - A tool for Container Signing, Verification and Storage in an OCI registry. - diff --git a/doc/cosign_triangulate.md b/doc/cosign_triangulate.md deleted file mode 100644 index 4533ed480..000000000 --- a/doc/cosign_triangulate.md +++ /dev/null @@ -1,37 +0,0 @@ -## cosign triangulate - -Outputs the located cosign image reference. This is the location cosign stores the specified artifact type. - -``` -cosign triangulate [flags] -``` - -### Examples - -``` - cosign triangulate -``` - -### Options - -``` - --allow-insecure-registry whether to allow insecure connections to registries. Don't use this for anything but testing - --attachment-tag-prefix [AttachmentTagPrefix]sha256-[TargetImageDigest].[AttachmentName] optional custom prefix to use for attached image tags. Attachment images are tagged as: [AttachmentTagPrefix]sha256-[TargetImageDigest].[AttachmentName] - -h, --help help for triangulate - --k8s-keychain whether to use the kubernetes keychain instead of the default keychain (supports workload identity). - --type string related attachment to triangulate (attestation|sbom|signature), default signature (default "signature") -``` - -### Options inherited from parent commands - -``` - --output-file string log output to a file - -t, --timeout duration timeout for commands (default 3m0s) - -d, --verbose log debug output - -y, --yes skip confirmation prompts for non-destructive operations -``` - -### SEE ALSO - -* [cosign](cosign.md) - A tool for Container Signing, Verification and Storage in an OCI registry. - diff --git a/doc/cosign_upload.md b/doc/cosign_upload.md deleted file mode 100644 index 6cf81ddc7..000000000 --- a/doc/cosign_upload.md +++ /dev/null @@ -1,25 +0,0 @@ -## cosign upload - -Provides utilities for uploading artifacts to a registry - -### Options - -``` - -h, --help help for upload -``` - -### Options inherited from parent commands - -``` - --output-file string log output to a file - -t, --timeout duration timeout for commands (default 3m0s) - -d, --verbose log debug output - -y, --yes skip confirmation prompts for non-destructive operations -``` - -### SEE ALSO - -* [cosign](cosign.md) - A tool for Container Signing, Verification and Storage in an OCI registry. -* [cosign upload blob](cosign_upload_blob.md) - Upload one or more blobs to the supplied container image address. -* [cosign upload wasm](cosign_upload_wasm.md) - Upload a wasm module to the supplied container image reference - diff --git a/doc/cosign_upload_blob.md b/doc/cosign_upload_blob.md deleted file mode 100644 index 1c2087498..000000000 --- a/doc/cosign_upload_blob.md +++ /dev/null @@ -1,50 +0,0 @@ -## cosign upload blob - -Upload one or more blobs to the supplied container image address. - -``` -cosign upload blob [flags] -``` - -### Examples - -``` - cosign upload blob -f - - # upload a blob named foo to the location specified by - cosign upload blob -f foo - - # upload a blob named foo to the location specified by , setting the os field to "MYOS". - cosign upload blob -f foo:MYOS - - # upload a blob named foo to the location specified by , setting the os field to "MYOS" and the platform field to "MYPLATFORM". - cosign upload blob -f foo:MYOS/MYPLATFORM - - # upload two blobs named foo-darwin and foo-linux to the location specified by , setting the os fields - cosign upload blob -f foo-darwin:darwin -f foo-linux:linux -``` - -### Options - -``` - --allow-insecure-registry whether to allow insecure connections to registries. Don't use this for anything but testing - --attachment-tag-prefix [AttachmentTagPrefix]sha256-[TargetImageDigest].[AttachmentName] optional custom prefix to use for attached image tags. Attachment images are tagged as: [AttachmentTagPrefix]sha256-[TargetImageDigest].[AttachmentName] - --ct string content type to set - -f, --files strings :[platform/arch] - -h, --help help for blob - --k8s-keychain whether to use the kubernetes keychain instead of the default keychain (supports workload identity). -``` - -### Options inherited from parent commands - -``` - --output-file string log output to a file - -t, --timeout duration timeout for commands (default 3m0s) - -d, --verbose log debug output - -y, --yes skip confirmation prompts for non-destructive operations -``` - -### SEE ALSO - -* [cosign upload](cosign_upload.md) - Provides utilities for uploading artifacts to a registry - diff --git a/doc/cosign_upload_wasm.md b/doc/cosign_upload_wasm.md deleted file mode 100644 index 93e4dd6fd..000000000 --- a/doc/cosign_upload_wasm.md +++ /dev/null @@ -1,37 +0,0 @@ -## cosign upload wasm - -Upload a wasm module to the supplied container image reference - -``` -cosign upload wasm [flags] -``` - -### Examples - -``` - cosign upload wasm -f foo.wasm -``` - -### Options - -``` - --allow-insecure-registry whether to allow insecure connections to registries. Don't use this for anything but testing - --attachment-tag-prefix [AttachmentTagPrefix]sha256-[TargetImageDigest].[AttachmentName] optional custom prefix to use for attached image tags. Attachment images are tagged as: [AttachmentTagPrefix]sha256-[TargetImageDigest].[AttachmentName] - -f, --file string path to the wasm file to upload - -h, --help help for wasm - --k8s-keychain whether to use the kubernetes keychain instead of the default keychain (supports workload identity). -``` - -### Options inherited from parent commands - -``` - --output-file string log output to a file - -t, --timeout duration timeout for commands (default 3m0s) - -d, --verbose log debug output - -y, --yes skip confirmation prompts for non-destructive operations -``` - -### SEE ALSO - -* [cosign upload](cosign_upload.md) - Provides utilities for uploading artifacts to a registry - diff --git a/doc/cosign_verify-attestation.md b/doc/cosign_verify-attestation.md deleted file mode 100644 index 6acd31adf..000000000 --- a/doc/cosign_verify-attestation.md +++ /dev/null @@ -1,94 +0,0 @@ -## cosign verify-attestation - -Verify an attestation on the supplied container image - -### Synopsis - -Verify an attestation on an image by checking the claims -against the transparency log. - -``` -cosign verify-attestation [flags] -``` - -### Examples - -``` - cosign verify-attestation --key || [ ...] - - # verify cosign attestations on the image - cosign verify-attestation - - # verify multiple images - cosign verify-attestation ... - - # additionally verify specified annotations - cosign verify-attestation -a key1=val1 -a key2=val2 - - # (experimental) additionally, verify with the transparency log - COSIGN_EXPERIMENTAL=1 cosign verify-attestation - - # verify image with public key - cosign verify-attestation --key cosign.pub - - # verify image attestations with an on-disk signed image from 'cosign save' - cosign verify-attestation --key cosign.pub --local-image - - # verify image with public key provided by URL - cosign verify-attestation --key https://host.for/ - - # verify image with public key stored in Google Cloud KMS - cosign verify-attestation --key gcpkms://projects//locations/global/keyRings//cryptoKeys/ - - # verify image with public key stored in Hashicorp Vault - cosign verify-attestation --key hashivault:/// - - # verify image with public key stored in GitLab with project name - cosign verify-attestation --key gitlab://[OWNER]/[PROJECT_NAME] - - # verify image with public key stored in GitLab with project id - cosign verify-attestation --key gitlab://[PROJECT_ID] - - # verify image with public key and validate attestation based on Rego policy - cosign verify-attestation --key cosign.pub --type --policy - - # verify image with public key and validate attestation based on CUE policy - cosign verify-attestation --key cosign.pub --type --policy -``` - -### Options - -``` - --allow-insecure-registry whether to allow insecure connections to registries. Don't use this for anything but testing - --attachment-tag-prefix [AttachmentTagPrefix]sha256-[TargetImageDigest].[AttachmentName] optional custom prefix to use for attached image tags. Attachment images are tagged as: [AttachmentTagPrefix]sha256-[TargetImageDigest].[AttachmentName] - --certificate string path to the public certificate - --certificate-chain string path to a list of CA certificates in PEM format which will be needed when building the certificate chain for the signing certificate. Must start with the parent intermediate CA certificate of the signing certificate and end with the root certificate - --certificate-email string the email expected in a valid Fulcio certificate - --certificate-oidc-issuer string the OIDC issuer expected in a valid Fulcio certificate, e.g. https://token.actions.githubusercontent.com or https://oauth2.sigstore.dev/auth - --check-claims whether to check the claims found (default true) - --enforce-sct whether to enforce that a certificate contain an embedded SCT, a proof of inclusion in a certificate transparency log - -h, --help help for verify-attestation - --k8s-keychain whether to use the kubernetes keychain instead of the default keychain (supports workload identity). - --key string path to the public key file, KMS URI or Kubernetes Secret - --local-image whether the specified image is a path to an image saved locally via 'cosign save' - -o, --output string output format for the signing image information (json|text) (default "json") - --policy strings specify CUE or Rego files will be using for validation - --rekor-url string [EXPERIMENTAL] address of rekor STL server (default "https://rekor.sigstore.dev") - --sk whether to use a hardware security key - --slot string security key slot to use for generated key (default: signature) (authentication|signature|card-authentication|key-management) - --type string specify a predicate type (slsaprovenance|link|spdx|vuln|custom) or an URI (default "custom") -``` - -### Options inherited from parent commands - -``` - --output-file string log output to a file - -t, --timeout duration timeout for commands (default 3m0s) - -d, --verbose log debug output - -y, --yes skip confirmation prompts for non-destructive operations -``` - -### SEE ALSO - -* [cosign](cosign.md) - A tool for Container Signing, Verification and Storage in an OCI registry. - diff --git a/doc/cosign_verify-blob.md b/doc/cosign_verify-blob.md deleted file mode 100644 index 6c17df3d0..000000000 --- a/doc/cosign_verify-blob.md +++ /dev/null @@ -1,93 +0,0 @@ -## cosign verify-blob - -Verify a signature on the supplied blob - -### Synopsis - -Verify a signature on the supplied blob input using the specified key reference. -You may specify either a key, a certificate or a kms reference to verify against. - If you use a key or a certificate, you must specify the path to them on disk. - -The signature may be specified as a path to a file or a base64 encoded string. -The blob may be specified as a path to a file or - for stdin. - -``` -cosign verify-blob [flags] -``` - -### Examples - -``` - cosign verify-blob (--key ||)|(--cert ) --signature - - # Verify a simple blob and message - cosign verify-blob --key cosign.pub --signature sig msg - - # Verify a simple blob with remote signature URL, both http and https schemes are supported - cosign verify-blob --key cosign.pub --signature http://host/my.sig - - # Verify a signature from an environment variable - cosign verify-blob --key cosign.pub --signature $sig msg - - # verify a signature with public key provided by URL - cosign verify-blob --key https://host.for/ --signature $sig msg - - # Verify a signature against a payload from another process using process redirection - cosign verify-blob --key cosign.pub --signature $sig <(git rev-parse HEAD) - - # Verify a signature against Azure Key Vault - cosign verify-blob --key azurekms://[VAULT_NAME][VAULT_URI]/[KEY] --signature $sig - - # Verify a signature against AWS KMS - cosign verify-blob --key awskms://[ENDPOINT]/[ID/ALIAS/ARN] --signature $sig - - # Verify a signature against Google Cloud KMS - cosign verify-blob --key gcpkms://projects/[PROJECT ID]/locations/[LOCATION]/keyRings/[KEYRING]/cryptoKeys/[KEY] --signature $sig - - # Verify a signature against Hashicorp Vault - cosign verify-blob --key hashivault://[KEY] --signature $sig - - # Verify a signature against GitLab with project name - cosign verify-blob --key gitlab://[OWNER]/[PROJECT_NAME] --signature $sig - - # Verify a signature against GitLab with project id - cosign verify-blob --key gitlab://[PROJECT_ID] --signature $sig - - # Verify a signature against a certificate - cosign verify-blob --cert --signature $sig - -``` - -### Options - -``` - --allow-insecure-registry whether to allow insecure connections to registries. Don't use this for anything but testing - --attachment-tag-prefix [AttachmentTagPrefix]sha256-[TargetImageDigest].[AttachmentName] optional custom prefix to use for attached image tags. Attachment images are tagged as: [AttachmentTagPrefix]sha256-[TargetImageDigest].[AttachmentName] - --bundle string path to bundle FILE - --certificate string path to the public certificate - --certificate-chain string path to a list of CA certificates in PEM format which will be needed when building the certificate chain for the signing certificate. Must start with the parent intermediate CA certificate of the signing certificate and end with the root certificate - --certificate-email string the email expected in a valid Fulcio certificate - --certificate-oidc-issuer string the OIDC issuer expected in a valid Fulcio certificate, e.g. https://token.actions.githubusercontent.com or https://oauth2.sigstore.dev/auth - --enforce-sct whether to enforce that a certificate contain an embedded SCT, a proof of inclusion in a certificate transparency log - -h, --help help for verify-blob - --k8s-keychain whether to use the kubernetes keychain instead of the default keychain (supports workload identity). - --key string path to the public key file, KMS URI or Kubernetes Secret - --rekor-url string [EXPERIMENTAL] address of rekor STL server (default "https://rekor.sigstore.dev") - --signature string signature content or path or remote URL - --sk whether to use a hardware security key - --slot string security key slot to use for generated key (default: signature) (authentication|signature|card-authentication|key-management) -``` - -### Options inherited from parent commands - -``` - --output-file string log output to a file - -t, --timeout duration timeout for commands (default 3m0s) - -d, --verbose log debug output - -y, --yes skip confirmation prompts for non-destructive operations -``` - -### SEE ALSO - -* [cosign](cosign.md) - A tool for Container Signing, Verification and Storage in an OCI registry. - diff --git a/doc/cosign_verify.md b/doc/cosign_verify.md deleted file mode 100644 index 8bfae767c..000000000 --- a/doc/cosign_verify.md +++ /dev/null @@ -1,103 +0,0 @@ -## cosign verify - -Verify a signature on the supplied container image - -### Synopsis - -Verify signature and annotations on an image by checking the claims -against the transparency log. - -``` -cosign verify [flags] -``` - -### Examples - -``` - cosign verify --key || [ ...] - - # verify cosign claims and signing certificates on the image - cosign verify - - # verify multiple images - cosign verify ... - - # additionally verify specified annotations - cosign verify -a key1=val1 -a key2=val2 - - # (experimental) additionally, verify with the transparency log - COSIGN_EXPERIMENTAL=1 cosign verify - - # verify image with an on-disk public key - cosign verify --key cosign.pub - - # verify image with an on-disk public key, manually specifying the - # signature digest algorithm - cosign verify --key cosign.pub --signature-digest-algorithm sha512 - - # verify image with an on-disk signed image from 'cosign save' - cosign verify --key cosign.pub --local-image - - # verify image with local certificate and certificate chain - cosign verify --cert cosign.crt --cert-chain chain.crt - - # verify image with public key provided by URL - cosign verify --key https://host.for/[FILE] - - # verify image with a key stored in an environment variable - cosign verify --key env://[ENV_VAR] - - # verify image with public key stored in Google Cloud KMS - cosign verify --key gcpkms://projects/[PROJECT]/locations/global/keyRings/[KEYRING]/cryptoKeys/[KEY] - - # verify image with public key stored in Hashicorp Vault - cosign verify --key hashivault://[KEY] - - # verify image with public key stored in a Kubernetes secret - cosign verify --key k8s://[NAMESPACE]/[KEY] - - # verify image with public key stored in GitLab with project name - cosign verify --key gitlab://[OWNER]/[PROJECT_NAME] - - # verify image with public key stored in GitLab with project id - cosign verify --key gitlab://[PROJECT_ID] -``` - -### Options - -``` - --allow-insecure-registry whether to allow insecure connections to registries. Don't use this for anything but testing - -a, --annotations strings extra key=value pairs to sign - --attachment string related image attachment to sign (sbom), default none - --attachment-tag-prefix [AttachmentTagPrefix]sha256-[TargetImageDigest].[AttachmentName] optional custom prefix to use for attached image tags. Attachment images are tagged as: [AttachmentTagPrefix]sha256-[TargetImageDigest].[AttachmentName] - --certificate string path to the public certificate - --certificate-chain string path to a list of CA certificates in PEM format which will be needed when building the certificate chain for the signing certificate. Must start with the parent intermediate CA certificate of the signing certificate and end with the root certificate - --certificate-email string the email expected in a valid Fulcio certificate - --certificate-oidc-issuer string the OIDC issuer expected in a valid Fulcio certificate, e.g. https://token.actions.githubusercontent.com or https://oauth2.sigstore.dev/auth - --check-claims whether to check the claims found (default true) - --enforce-sct whether to enforce that a certificate contain an embedded SCT, a proof of inclusion in a certificate transparency log - -h, --help help for verify - --k8s-keychain whether to use the kubernetes keychain instead of the default keychain (supports workload identity). - --key string path to the public key file, KMS URI or Kubernetes Secret - --local-image whether the specified image is a path to an image saved locally via 'cosign save' - -o, --output string output format for the signing image information (json|text) (default "json") - --rekor-url string [EXPERIMENTAL] address of rekor STL server (default "https://rekor.sigstore.dev") - --signature string signature content or path or remote URL - --signature-digest-algorithm string digest algorithm to use when processing a signature (sha224|sha256|sha384|sha512) (default "sha256") - --sk whether to use a hardware security key - --slot string security key slot to use for generated key (default: signature) (authentication|signature|card-authentication|key-management) -``` - -### Options inherited from parent commands - -``` - --output-file string log output to a file - -t, --timeout duration timeout for commands (default 3m0s) - -d, --verbose log debug output - -y, --yes skip confirmation prompts for non-destructive operations -``` - -### SEE ALSO - -* [cosign](cosign.md) - A tool for Container Signing, Verification and Storage in an OCI registry. - diff --git a/doc/cosign_version.md b/doc/cosign_version.md deleted file mode 100644 index 3bb4929d9..000000000 --- a/doc/cosign_version.md +++ /dev/null @@ -1,28 +0,0 @@ -## cosign version - -Prints the version - -``` -cosign version [flags] -``` - -### Options - -``` - -h, --help help for version - --json print JSON instead of text -``` - -### Options inherited from parent commands - -``` - --output-file string log output to a file - -t, --timeout duration timeout for commands (default 3m0s) - -d, --verbose log debug output - -y, --yes skip confirmation prompts for non-destructive operations -``` - -### SEE ALSO - -* [cosign](cosign.md) - A tool for Container Signing, Verification and Storage in an OCI registry. - diff --git a/go.mod b/go.mod index c7a6d5abc..8bd0f62cb 100644 --- a/go.mod +++ b/go.mod @@ -8,9 +8,7 @@ require ( github.com/armon/go-metrics v0.4.0 github.com/armon/go-radix v1.0.0 github.com/aws/aws-sdk-go-v2 v1.16.5 - github.com/awslabs/amazon-ecr-credential-helper/ecr-login v0.0.0-20220228164355-396b2034c795 github.com/cenkalti/backoff/v3 v3.2.2 - github.com/chrismellard/docker-credential-acr-env v0.0.0-20220119192733-fe33c00cee21 github.com/cyberphone/json-canonicalization v0.0.0-20210823021906-dc406ceaf94b github.com/go-openapi/runtime v0.24.1 github.com/go-openapi/strfmt v0.21.2 @@ -44,7 +42,6 @@ require ( github.com/in-toto/in-toto-golang v0.3.4-0.20211211042327-af1f9fb822bf github.com/kelseyhightower/envconfig v1.4.0 github.com/letsencrypt/boulder v0.0.0-20220331220046-b23ab962616e - github.com/manifoldco/promptui v0.9.0 github.com/miekg/pkcs11 v1.1.1 github.com/mitchellh/copystructure v1.2.0 github.com/mitchellh/go-homedir v1.1.0 @@ -59,14 +56,11 @@ require ( github.com/sigstore/rekor v0.4.1-0.20220114213500-23f583409af3 github.com/sigstore/sigstore v1.2.1-0.20220424143412-3d41663116d5 github.com/spf13/cobra v1.4.0 - github.com/spf13/pflag v1.0.5 - github.com/spf13/viper v1.12.0 github.com/spiffe/go-spiffe/v2 v2.1.0 github.com/stretchr/testify v1.7.2 github.com/theupdateframework/go-tuf v0.3.0 github.com/titanous/rocacheck v0.0.0-20171023193734-afe73141d399 github.com/transparency-dev/merkle v0.0.1 - github.com/withfig/autocomplete-tools/packages/cobra v0.0.0-20220122124547-31d3821a6898 github.com/xanzy/go-gitlab v0.68.0 go.uber.org/atomic v1.9.0 go.uber.org/zap v1.21.0 @@ -134,6 +128,7 @@ require ( github.com/aws/aws-sdk-go-v2/service/sso v1.10.0 // indirect github.com/aws/aws-sdk-go-v2/service/sts v1.15.0 // indirect github.com/aws/smithy-go v1.11.3 // indirect + github.com/awslabs/amazon-ecr-credential-helper/ecr-login v0.0.0-20220228164355-396b2034c795 // indirect github.com/benbjohnson/clock v1.1.0 // indirect github.com/beorn7/perks v1.0.1 // indirect github.com/bgentry/speakeasy v0.1.0 // indirect @@ -143,7 +138,7 @@ require ( github.com/bytecodealliance/wasmtime-go v0.33.1 // indirect github.com/census-instrumentation/opencensus-proto v0.3.0 // indirect github.com/cespare/xxhash/v2 v2.1.2 // indirect - github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e // indirect + github.com/chrismellard/docker-credential-acr-env v0.0.0-20220119192733-fe33c00cee21 // indirect github.com/cncf/udpa/go v0.0.0-20210930031921-04548b0d99d4 // indirect github.com/cncf/xds/go v0.0.0-20211130200136-a8f946100490 // indirect github.com/cockroachdb/apd/v2 v2.0.1 // indirect @@ -254,6 +249,8 @@ require ( github.com/spf13/afero v1.8.2 // indirect github.com/spf13/cast v1.5.0 // indirect github.com/spf13/jwalterweatherman v1.1.0 // indirect + github.com/spf13/pflag v1.0.5 // indirect + github.com/spf13/viper v1.12.0 // indirect github.com/subosito/gotenv v1.3.0 // indirect github.com/syndtr/goleveldb v1.0.1-0.20210819022825-2ae1ddf74ef7 // indirect github.com/tent/canonical-json-go v0.0.0-20130607151641-96e4ba3a7613 // indirect diff --git a/go.sum b/go.sum index 3170945fd..b007091aa 100644 --- a/go.sum +++ b/go.sum @@ -463,11 +463,8 @@ github.com/checkpoint-restore/go-criu/v4 v4.1.0/go.mod h1:xUQBLp4RLc5zJtWY++yjOo github.com/checkpoint-restore/go-criu/v5 v5.0.0/go.mod h1:cfwC0EG7HMUenopBsUf9d89JlCLQIfgVcNsNN0t6T2M= github.com/chrismellard/docker-credential-acr-env v0.0.0-20220119192733-fe33c00cee21 h1:XlpL9EHrPOBJMLDDOf35/G4t5rGAFNNAZQ3cDcWavtc= github.com/chrismellard/docker-credential-acr-env v0.0.0-20220119192733-fe33c00cee21/go.mod h1:Zlre/PVxuSI9y6/UV4NwGixQ48RHQDSPiUkofr6rbMU= -github.com/chzyer/logex v1.1.10 h1:Swpa1K6QvQznwJRcfTfQJmTE72DqScAa40E+fbHEXEE= github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI= -github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e h1:fY5BOSpyZCqRo5OhCuC+XN+r/bBCmeuuJtjz+bCNIf8= github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI= -github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1 h1:q763qf9huN11kDQavWsoZXJNW3xEE4JJyHa5Q25/sd8= github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU= github.com/cilium/ebpf v0.0.0-20200110133405-4032b1d8aae3/go.mod h1:MA5e5Lr8slmEg9bt0VpxxWqJlO4iwu3FBdHUzV7wQVg= github.com/cilium/ebpf v0.0.0-20200702112145-1c8d4c9ef775/go.mod h1:7cR51M8ViRLIdUjrmSXlK9pkrsDlLHbO8jiB8X8JnOc= @@ -1606,8 +1603,6 @@ github.com/mailru/easyjson v0.7.1/go.mod h1:KAzv3t3aY1NaHWoQz1+4F1ccyAH66Jk7yos7 github.com/mailru/easyjson v0.7.6/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc= github.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0= github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc= -github.com/manifoldco/promptui v0.9.0 h1:3V4HzJk1TtXW1MTZMP7mdlwbBpIinw3HztaIlYthEiA= -github.com/manifoldco/promptui v0.9.0/go.mod h1:ka04sppxSGFAtxX0qhlYQjISsg9mR4GWtQEhdbn6Pgg= github.com/maratori/testpackage v1.0.1/go.mod h1:ddKdw+XG0Phzhx8BFDTKgpWP4i7MpApTE5fXSKAqwDU= github.com/markbates/errx v1.1.0/go.mod h1:PLa46Oex9KNbVDZhKel8v1OT7hD5JZ2eI7AHhA0wswc= github.com/markbates/oncer v0.0.0-20181203154359-bf2de49a0be2/go.mod h1:Ld9puTsIW75CHf65OeIOkyKbteujpZVXDpWK6YGZbxE= @@ -2241,8 +2236,6 @@ github.com/weppos/publicsuffix-go v0.15.1-0.20210807195340-dc689ff0bb59/go.mod h github.com/weppos/publicsuffix-go v0.15.1-0.20220329081811-9a40b608a236/go.mod h1:HYux0V0Zi04bHNwOHy4cXJVz/TQjYonnF6aoYhj+3QE= github.com/willf/bitset v1.1.11-0.20200630133818-d5bec3311243/go.mod h1:RjeCKbqT1RxIR/KWY6phxZiaY1IyutSBfGjNPySAYV4= github.com/willf/bitset v1.1.11/go.mod h1:83CECat5yLh5zVOf4P1ErAgKA5UDvKtgyUABdr3+MjI= -github.com/withfig/autocomplete-tools/packages/cobra v0.0.0-20220122124547-31d3821a6898 h1:2Z+iziYPiyWk5hVJ3EYLn/i33Tj5ukytaJA0Th9tbgc= -github.com/withfig/autocomplete-tools/packages/cobra v0.0.0-20220122124547-31d3821a6898/go.mod h1:cKObXQ6PVFO7bHUd5jpApXvMIt55Ewz7UdMiC05ONxI= github.com/xanzy/go-gitlab v0.31.0/go.mod h1:sPLojNBn68fMUWSxIJtdVVIP8uSBYqesTfDUseX11Ug= github.com/xanzy/go-gitlab v0.68.0 h1:b2iMQHgZ1V+NyRqLRJVv6RFfr4xnd/AASeS/PETYL0Y= github.com/xanzy/go-gitlab v0.68.0/go.mod h1:o4yExCtdaqlM8YGdDJWuZoBmfxBsmA9TPEjs9mx1UO4= diff --git a/pkg/sget/sget.go b/pkg/sget/sget.go deleted file mode 100644 index 5cf9307b7..000000000 --- a/pkg/sget/sget.go +++ /dev/null @@ -1,130 +0,0 @@ -// -// Copyright 2021 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 sget - -import ( - "context" - "errors" - "fmt" - "io" - - "github.com/google/go-containerregistry/pkg/authn" - "github.com/google/go-containerregistry/pkg/name" - "github.com/google/go-containerregistry/pkg/v1/remote" - - "github.com/sigstore/policy-controller/cmd/cosign/cli/fulcio" - "github.com/sigstore/policy-controller/cmd/cosign/cli/options" - "github.com/sigstore/policy-controller/cmd/cosign/cli/verify" - "github.com/sigstore/policy-controller/pkg/cosign" - ociremote "github.com/sigstore/policy-controller/pkg/oci/remote" - sigs "github.com/sigstore/policy-controller/pkg/signature" -) - -func New(image, key string, out io.Writer) *SecureGet { - return &SecureGet{ - ImageRef: image, - KeyRef: key, - Out: out, - } -} - -type SecureGet struct { - ImageRef string - KeyRef string - Out io.Writer -} - -func (sg *SecureGet) Do(ctx context.Context) error { - ref, err := name.ParseReference(sg.ImageRef) - if err != nil { - return err - } - - opts := []remote.Option{ - remote.WithAuthFromKeychain(authn.DefaultKeychain), - remote.WithContext(ctx), - } - - co := &cosign.CheckOpts{ - ClaimVerifier: cosign.SimpleClaimVerifier, - RegistryClientOpts: []ociremote.Option{ociremote.WithRemoteOptions(opts...)}, - } - if _, ok := ref.(name.Tag); ok { - if sg.KeyRef == "" && !options.EnableExperimental() { - return errors.New("public key must be specified when fetching by tag, you must fetch by digest or supply a public key") - } - } - // Overwrite "ref" with a digest to avoid a race where we verify the tag, - // and then access the file through the tag. This has a race where we - // might download content that isn't what we verified. - ref, err = ociremote.ResolveDigest(ref, co.RegistryClientOpts...) - if err != nil { - return err - } - - if sg.KeyRef != "" { - pub, err := sigs.LoadPublicKey(ctx, sg.KeyRef) - if err != nil { - return err - } - co.SigVerifier = pub - } - - if co.SigVerifier != nil || options.EnableExperimental() { - // NB: There are only 2 kinds of verification right now: - // 1. You gave us the public key explicitly to verify against so co.SigVerifier is non-nil or, - // 2. We're going to find an x509 certificate on the signature and verify against Fulcio root trust - // TODO(nsmith5): Refactor this verification logic to pass back _how_ verification - // was performed so we don't need to use this fragile logic here. - fulcioVerified := (co.SigVerifier == nil) - - co.RootCerts, err = fulcio.GetRoots() - if err != nil { - return fmt.Errorf("getting Fulcio roots: %w", err) - } - co.IntermediateCerts, err = fulcio.GetIntermediates() - if err != nil { - return fmt.Errorf("getting Fulcio intermediates: %w", err) - } - - sp, bundleVerified, err := cosign.VerifyImageSignatures(ctx, ref, co) - if err != nil { - return err - } - verify.PrintVerificationHeader(sg.ImageRef, co, bundleVerified, fulcioVerified) - verify.PrintVerification(sg.ImageRef, sp, "text") - } - - // TODO(mattmoor): Depending on what this is, use the higher-level stuff. - img, err := remote.Image(ref, opts...) - if err != nil { - return err - } - layers, err := img.Layers() - if err != nil { - return err - } - if len(layers) != 1 { - return errors.New("invalid artifact") - } - rc, err := layers[0].Compressed() - if err != nil { - return err - } - - _, err = io.Copy(sg.Out, rc) - return err -} diff --git a/specs/ATTESTATION_SPEC.md b/specs/ATTESTATION_SPEC.md deleted file mode 100644 index 9c129d2f9..000000000 --- a/specs/ATTESTATION_SPEC.md +++ /dev/null @@ -1,54 +0,0 @@ -# Cosign Attestation Specifications - -This document aims to describe how `cosign` attaches `Attestations` to container images. - -The goal is to specify the behavior well enough to promote other implementations and enable interoperability. -Attestations attached with `cosign` should be retrievable in other tools, and vice-versa. - -This document focuses on the layout of attestations within an [OCI Image Manifest V1](https://github.com/opencontainers/image-spec/blob/master/manifest.md) object. - -This document assumes you are using the In-Toto [Attestation](https://github.com/in-toto/attestation) format, serialized as a `DSSE` envelope -Other formats can be used, and the `mediaType` property should describe the format of a particular attestation, but implementations may not understand them. -The DSSE envelope format is defined [here](https://github.com/secure-systems-lab/dsse/blob/master/envelope.md#dsse-envelope) and uses the `mediaType`: `application/vnd.dsse.envelope.v1+json`. - -Multiple Attestations may be "attached" to one image. -Each Attestation may refer to the entire image, or to a specific part of that image. -This is indicated via the `subject` field of the `Statement` inside the `Attestation`. - -Attestations attached to a container image are generally assumed to refer to that image in some way. - -## Overall Layout - -An `Attestation` object is represented as an [OCI Image Manifest V1](https://github.com/opencontainers/image-spec/blob/master/manifest.md). - -Each individual `Attestation` is represented as a `layer`, using a standard `descriptor`. -The `layers` list is ordered, but no order is assumed or important for the `Attestations`. - -Here is an example manifest containing one `Attestation`: - -```json -{ - "schemaVersion": 2, - "config": { - "mediaType": "application/vnd.oci.image.config.v1+json", - "size": 233, - "digest": "sha256:83bd5fb5b39f65f28e50a86d48fa79c07880befc292d92eebdc18531054b070c" - }, - "layers": [ - { - "mediaType": "application/vnd.dsse.envelope.v1+json", - "size": 246, - "digest": "sha256:ed3ad03d3b87843b5419d7dce9d50a3e0f45554b2ba93bf378611cae6b450cff", - } - ] -} -``` - -## Subject Verification - -`Attestations` MAY refer to multiple `subjects`. - -When verifying an attestation for a container image, implementations MUST verify the relationship between the `subject` field and the container image. -Attestations MAY reference the entire container image or a portion of it. - -Implementations MUST support `Attestations` that reference the entire container image, other relationship types are optional. diff --git a/specs/COSIGN_PREDICATE_SPEC.md b/specs/COSIGN_PREDICATE_SPEC.md deleted file mode 100644 index 0e899b5eb..000000000 --- a/specs/COSIGN_PREDICATE_SPEC.md +++ /dev/null @@ -1,31 +0,0 @@ -# Cosign Generic Predicate Specification - -`Cosign` supports working with [In-Toto Attestations](https://github.com/in-toto/attestation) using the predicate model. -Several well-known predicates are supported natively, but `cosign` also supports a simple, generic, format for data that -doesn't fit well into other types. - -The format for this is defined as follows: - -`data`: Raw data to place in the attestation. This is a base64-encoded string of bytes. -`timestamp`: The timestamp the attestation was generated at in the RFC3339 format in the UTC timezone. - -Here is an example attestation containing a data file containing `foo`: - -```json -{ - "_type": "https://in-toto.io/Statement/v0.1", - "predicateType": "cosign.sigstore.dev/attestation/v1", - "subject": [ - { - "name": "us.gcr.io/dlorenc-vmtest2/demo", - "digest": { - "sha256": "124e1fdee94fe5c5f902bc94da2d6e2fea243934c74e76c2368acdc8d3ac7155" - } - } - ], - "predicate": { - "Data": "foo\n", - "Timestamp": "2021-08-11T14:51:09Z" - } -} -``` \ No newline at end of file diff --git a/specs/COSIGN_VULN_ATTESTATION_SPEC.md b/specs/COSIGN_VULN_ATTESTATION_SPEC.md deleted file mode 100644 index 67dbbdb1e..000000000 --- a/specs/COSIGN_VULN_ATTESTATION_SPEC.md +++ /dev/null @@ -1,431 +0,0 @@ -# Cosign Vulnerability Scan Record Attestation Specification - -`Cosign` is heavily using [In-toto Attestations](https://github.com/in-toto/attestation) predicate models in its own -codebase. But this is not the only option you have while working with predicates in cosign. `Cosign` already defines its -own predicates: [Generic Predicate Specification](COSIGN_PREDICATE_SPEC.md). This `Vulnerability Scan` -attestation is one of them. - -Let's talk a bit about the history of this specification. We first mentioned this idea -in [in-toto attestation](https://github.com/in-toto/attestation/issues/58) repository. So many people interested in this -issue, and shared ideas about which parts are necessary which parts are not to make that specification well-purposed. -There is an also cross [issue](https://github.com/sigstore/cosign/issues/442) on cosign side that we discussed on it. - -And the final format for this is defined as follows: - -```json -{ - "_type": "https://in-toto.io/Statement/v0.1", - "subject": [ - { - ... - } - ], - // Predicate: - "predicateType": "cosign.sigstore.dev/attestation/vuln/v1", - "predicate": { - "invocation": { - "parameters": [], - // [ "--format=json", "--skip-db-update" ] - "uri": "", - // https://github.com/developer-guy/alpine/actions/runs/1071875574 - "event_id": "", - // 1071875574 - "builder.id": "" - // GitHub Actions - }, - "scanner": { - "uri": "", - // pkg:github/aquasecurity/trivy@244fd47e07d1004f0aed9 - "version": "", - // 0.19.2 - "db": { - "uri": "", - // pkg:github/aquasecurity/trivy-db/commit/4c76bb580b2736d67751410fa4ab66d2b6b9b27d - "version": "" - // "v1-2021080612" - }, - "result": {} - }, - "metadata": { - "scanStartedOn": "", - // 2021-08-06T17:45:50.52Z - "scanFinishedOn": "" - // 2021-08-06T17:50:50.52Z - } - } -} -``` - -## Fields - -**scanner** - -> There are lots of container image scanners such as Trivy, Grype, Clair, etc. -> This field describes which scanner is used while performing a container image scan, -> as well as version information and which Vulnerability DB is used. - -**scanner.uri** string (ResourceURI), optional - -> > URI indicating the identity of the source of the scanner. - -**scanner.version** string (ResourceURI), optional - -> The version of the scanner. - -**scanner.db.uri** string (ResourceURI), optional - -> URI indicating the identity of the source of the Vulnerability DB. - -**scanner.db.version** string, optional - -> The version of the Vulnerability DB. - -**scanner.result** object - -> This is the most important part of this field because it'll store the scan result as a whole. So, people might want -> to use this field to take decisions based on them by making use of Policy Engines tooling whether allow or deny these images. - -**metadata.buildStartedOn string (Timestamp), required** - -> The timestamp of when the build started. - -**metadata.buildFinishedOn string (Timestamp), required** - -> The timestamp of when the build completed. - -```shell -$ trivy image -f json alpine:3.12 -``` - -
- -Scan Result - -```json -{ - "SchemaVersion": 2, - "ArtifactName": "alpine:3.12", - "ArtifactType": "container_image", - "Metadata": { - "OS": { - "Family": "alpine", - "Name": "3.12.9" - }, - "ImageID": "sha256:b0925e0819214cd29937af66dbaf0e6fe239997faea60922cc890f9984512507", - "DiffIDs": [ - "sha256:eb4bde6b29a6746e0779f80a09ca6f0806de61475059f7d56d6e20f6cc2e15f7" - ], - "RepoTags": [ - "alpine:3.12" - ], - "RepoDigests": [ - "alpine@sha256:d9459083f962de6bd980ae6a05be2a4cf670df6a1d898157bceb420342bec280" - ], - "ImageConfig": { - "architecture": "amd64", - "container": "385e1cc96cc7482dfb6847e293bb24baecd3f48a49791b9b45e297204b160287", - "created": "2021-11-12T17:20:08.442217528Z", - "docker_version": "20.10.7", - "history": [ - { - "created": "2021-11-12T17:20:08.190319702Z", - "created_by": "/bin/sh -c #(nop) ADD file:8f5bc5ce64ef781adadca88e4004e17affc72e6f20dbd08b9c478def12fe1dd3 in / " - }, - { - "created": "2021-11-12T17:20:08.442217528Z", - "created_by": "/bin/sh -c #(nop) CMD [\"/bin/sh\"]", - "empty_layer": true - } - ], - "os": "linux", - "rootfs": { - "type": "layers", - "diff_ids": [ - "sha256:eb4bde6b29a6746e0779f80a09ca6f0806de61475059f7d56d6e20f6cc2e15f7" - ] - }, - "config": { - "Cmd": [ - "/bin/sh" - ], - "Env": [ - "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin" - ], - "Image": "sha256:7d1c1e4b291dc9519b43a2b9c9330655927f6dfde90d36ef5fd16b2ae0f28bbc" - } - } - }, - "Results": [ - { - "Target": "alpine:3.12 (alpine 3.12.9)", - "Class": "os-pkgs", - "Type": "alpine", - "Vulnerabilities": [ - { - "VulnerabilityID": "CVE-2021-28831", - "PkgName": "busybox", - "InstalledVersion": "1.31.1-r21", - "FixedVersion": "1.32.1-r4", - "Layer": { - "Digest": "sha256:8572bc8fb8a32061648dd183b2c0451c82be1bd053a4ea8fae991436b92faebb", - "DiffID": "sha256:eb4bde6b29a6746e0779f80a09ca6f0806de61475059f7d56d6e20f6cc2e15f7" - }, - "SeveritySource": "nvd", - "PrimaryURL": "https://avd.aquasec.com/nvd/cve-2021-28831", - "Title": "busybox: invalid free or segmentation fault via malformed gzip data", - "Description": "decompress_gunzip.c in BusyBox through 1.32.1 mishandles the error bit on the huft_build result pointer, with a resultant invalid free or segmentation fault, via malformed gzip data.", - "Severity": "HIGH", - "CweIDs": [ - "CWE-755" - ], - "CVSS": { - "nvd": { - "V2Vector": "AV:N/AC:L/Au:N/C:N/I:N/A:P", - "V3Vector": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H", - "V2Score": 5, - "V3Score": 7.5 - }, - "redhat": { - "V3Vector": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H", - "V3Score": 7.5 - } - }, - "References": [ - "https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2021-28831", - "https://git.busybox.net/busybox/commit/?id=f25d254dfd4243698c31a4f3153d4ac72aa9e9bd", - "https://lists.debian.org/debian-lts-announce/2021/04/msg00001.html", - "https://lists.fedoraproject.org/archives/list/package-announce@lists.fedoraproject.org/message/3UDQGJRECXFS5EZVDH2OI45FMO436AC4/", - "https://lists.fedoraproject.org/archives/list/package-announce@lists.fedoraproject.org/message/Z7ZIFKPRR32ZYA3WAA2NXFA3QHHOU6FJ/", - "https://lists.fedoraproject.org/archives/list/package-announce@lists.fedoraproject.org/message/ZASBW7QRRLY5V2R44MQ4QQM4CZIDHM2U/", - "https://security.gentoo.org/glsa/202105-09", - "https://ubuntu.com/security/notices/USN-5179-1" - ], - "PublishedDate": "2021-03-19T05:15:00Z", - "LastModifiedDate": "2021-05-26T10:15:00Z" - }, - { - "VulnerabilityID": "CVE-2021-28831", - "PkgName": "ssl_client", - "InstalledVersion": "1.31.1-r21", - "FixedVersion": "1.32.1-r4", - "Layer": { - "Digest": "sha256:8572bc8fb8a32061648dd183b2c0451c82be1bd053a4ea8fae991436b92faebb", - "DiffID": "sha256:eb4bde6b29a6746e0779f80a09ca6f0806de61475059f7d56d6e20f6cc2e15f7" - }, - "SeveritySource": "nvd", - "PrimaryURL": "https://avd.aquasec.com/nvd/cve-2021-28831", - "Title": "busybox: invalid free or segmentation fault via malformed gzip data", - "Description": "decompress_gunzip.c in BusyBox through 1.32.1 mishandles the error bit on the huft_build result pointer, with a resultant invalid free or segmentation fault, via malformed gzip data.", - "Severity": "HIGH", - "CweIDs": [ - "CWE-755" - ], - "CVSS": { - "nvd": { - "V2Vector": "AV:N/AC:L/Au:N/C:N/I:N/A:P", - "V3Vector": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H", - "V2Score": 5, - "V3Score": 7.5 - }, - "redhat": { - "V3Vector": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H", - "V3Score": 7.5 - } - }, - "References": [ - "https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2021-28831", - "https://git.busybox.net/busybox/commit/?id=f25d254dfd4243698c31a4f3153d4ac72aa9e9bd", - "https://lists.debian.org/debian-lts-announce/2021/04/msg00001.html", - "https://lists.fedoraproject.org/archives/list/package-announce@lists.fedoraproject.org/message/3UDQGJRECXFS5EZVDH2OI45FMO436AC4/", - "https://lists.fedoraproject.org/archives/list/package-announce@lists.fedoraproject.org/message/Z7ZIFKPRR32ZYA3WAA2NXFA3QHHOU6FJ/", - "https://lists.fedoraproject.org/archives/list/package-announce@lists.fedoraproject.org/message/ZASBW7QRRLY5V2R44MQ4QQM4CZIDHM2U/", - "https://security.gentoo.org/glsa/202105-09", - "https://ubuntu.com/security/notices/USN-5179-1" - ], - "PublishedDate": "2021-03-19T05:15:00Z", - "LastModifiedDate": "2021-05-26T10:15:00Z" - } - ] - } - ] -} -``` - -
- -Here is an example predicate containing a vulnerability scan result above: - -```json -{ - "predicate": { - "invocation": { - "parameters": [ - "--format=json" - ], - "uri": "https://github.com/developer-guy/alpine/actions/runs/1071875574", - "event_id": "1071875574", - "builder.id": "github actions" - }, - "scanner": { - "uri": "pkg:github/aquasecurity/trivy@244fd47e07d1004f0aed9", - "version": "0.19.2", - "db": { - "uri": "pkg:github/aquasecurity/trivy-db/commit/4c76bb580b2736d67751410fa4ab66d2b6b9b27d", - "version": "v1-2021080612" - }, - "result": { - "SchemaVersion": 2, - "ArtifactName": "alpine:3.12", - "ArtifactType": "container_image", - "Metadata": { - "OS": { - "Family": "alpine", - "Name": "3.12.9" - }, - "ImageID": "sha256:b0925e0819214cd29937af66dbaf0e6fe239997faea60922cc890f9984512507", - "DiffIDs": [ - "sha256:eb4bde6b29a6746e0779f80a09ca6f0806de61475059f7d56d6e20f6cc2e15f7" - ], - "RepoTags": [ - "alpine:3.12" - ], - "RepoDigests": [ - "alpine@sha256:d9459083f962de6bd980ae6a05be2a4cf670df6a1d898157bceb420342bec280" - ], - "ImageConfig": { - "architecture": "amd64", - "container": "385e1cc96cc7482dfb6847e293bb24baecd3f48a49791b9b45e297204b160287", - "created": "2021-11-12T17:20:08.442217528Z", - "docker_version": "20.10.7", - "history": [ - { - "created": "2021-11-12T17:20:08.190319702Z", - "created_by": "/bin/sh -c #(nop) ADD file:8f5bc5ce64ef781adadca88e4004e17affc72e6f20dbd08b9c478def12fe1dd3 in / " - }, - { - "created": "2021-11-12T17:20:08.442217528Z", - "created_by": "/bin/sh -c #(nop) CMD [\"/bin/sh\"]", - "empty_layer": true - } - ], - "os": "linux", - "rootfs": { - "type": "layers", - "diff_ids": [ - "sha256:eb4bde6b29a6746e0779f80a09ca6f0806de61475059f7d56d6e20f6cc2e15f7" - ] - }, - "config": { - "Cmd": [ - "/bin/sh" - ], - "Env": [ - "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin" - ], - "Image": "sha256:7d1c1e4b291dc9519b43a2b9c9330655927f6dfde90d36ef5fd16b2ae0f28bbc" - } - } - }, - "Results": [ - { - "Target": "alpine:3.12 (alpine 3.12.9)", - "Class": "os-pkgs", - "Type": "alpine", - "Vulnerabilities": [ - { - "VulnerabilityID": "CVE-2021-28831", - "PkgName": "busybox", - "InstalledVersion": "1.31.1-r21", - "FixedVersion": "1.32.1-r4", - "Layer": { - "Digest": "sha256:8572bc8fb8a32061648dd183b2c0451c82be1bd053a4ea8fae991436b92faebb", - "DiffID": "sha256:eb4bde6b29a6746e0779f80a09ca6f0806de61475059f7d56d6e20f6cc2e15f7" - }, - "SeveritySource": "nvd", - "PrimaryURL": "https://avd.aquasec.com/nvd/cve-2021-28831", - "Title": "busybox: invalid free or segmentation fault via malformed gzip data", - "Description": "decompress_gunzip.c in BusyBox through 1.32.1 mishandles the error bit on the huft_build result pointer, with a resultant invalid free or segmentation fault, via malformed gzip data.", - "Severity": "HIGH", - "CweIDs": [ - "CWE-755" - ], - "CVSS": { - "nvd": { - "V2Vector": "AV:N/AC:L/Au:N/C:N/I:N/A:P", - "V3Vector": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H", - "V2Score": 5, - "V3Score": 7.5 - }, - "redhat": { - "V3Vector": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H", - "V3Score": 7.5 - } - }, - "References": [ - "https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2021-28831", - "https://git.busybox.net/busybox/commit/?id=f25d254dfd4243698c31a4f3153d4ac72aa9e9bd", - "https://lists.debian.org/debian-lts-announce/2021/04/msg00001.html", - "https://lists.fedoraproject.org/archives/list/package-announce@lists.fedoraproject.org/message/3UDQGJRECXFS5EZVDH2OI45FMO436AC4/", - "https://lists.fedoraproject.org/archives/list/package-announce@lists.fedoraproject.org/message/Z7ZIFKPRR32ZYA3WAA2NXFA3QHHOU6FJ/", - "https://lists.fedoraproject.org/archives/list/package-announce@lists.fedoraproject.org/message/ZASBW7QRRLY5V2R44MQ4QQM4CZIDHM2U/", - "https://security.gentoo.org/glsa/202105-09", - "https://ubuntu.com/security/notices/USN-5179-1" - ], - "PublishedDate": "2021-03-19T05:15:00Z", - "LastModifiedDate": "2021-05-26T10:15:00Z" - }, - { - "VulnerabilityID": "CVE-2021-28831", - "PkgName": "ssl_client", - "InstalledVersion": "1.31.1-r21", - "FixedVersion": "1.32.1-r4", - "Layer": { - "Digest": "sha256:8572bc8fb8a32061648dd183b2c0451c82be1bd053a4ea8fae991436b92faebb", - "DiffID": "sha256:eb4bde6b29a6746e0779f80a09ca6f0806de61475059f7d56d6e20f6cc2e15f7" - }, - "SeveritySource": "nvd", - "PrimaryURL": "https://avd.aquasec.com/nvd/cve-2021-28831", - "Title": "busybox: invalid free or segmentation fault via malformed gzip data", - "Description": "decompress_gunzip.c in BusyBox through 1.32.1 mishandles the error bit on the huft_build result pointer, with a resultant invalid free or segmentation fault, via malformed gzip data.", - "Severity": "HIGH", - "CweIDs": [ - "CWE-755" - ], - "CVSS": { - "nvd": { - "V2Vector": "AV:N/AC:L/Au:N/C:N/I:N/A:P", - "V3Vector": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H", - "V2Score": 5, - "V3Score": 7.5 - }, - "redhat": { - "V3Vector": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H", - "V3Score": 7.5 - } - }, - "References": [ - "https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2021-28831", - "https://git.busybox.net/busybox/commit/?id=f25d254dfd4243698c31a4f3153d4ac72aa9e9bd", - "https://lists.debian.org/debian-lts-announce/2021/04/msg00001.html", - "https://lists.fedoraproject.org/archives/list/package-announce@lists.fedoraproject.org/message/3UDQGJRECXFS5EZVDH2OI45FMO436AC4/", - "https://lists.fedoraproject.org/archives/list/package-announce@lists.fedoraproject.org/message/Z7ZIFKPRR32ZYA3WAA2NXFA3QHHOU6FJ/", - "https://lists.fedoraproject.org/archives/list/package-announce@lists.fedoraproject.org/message/ZASBW7QRRLY5V2R44MQ4QQM4CZIDHM2U/", - "https://security.gentoo.org/glsa/202105-09", - "https://ubuntu.com/security/notices/USN-5179-1" - ], - "PublishedDate": "2021-03-19T05:15:00Z", - "LastModifiedDate": "2021-05-26T10:15:00Z" - } - ] - } - ] - } - }, - "metadata": { - "scanStartedOn": "2021-08-06T17:45:50.52Z", - "scanFinishedOn": "2021-08-06T17:50:50.52Z" - } - } -} -``` - diff --git a/specs/SBOM_SPEC.md b/specs/SBOM_SPEC.md deleted file mode 100644 index 9ba685de5..000000000 --- a/specs/SBOM_SPEC.md +++ /dev/null @@ -1,143 +0,0 @@ -# Cosign SBOM Specifications - -This document aims to describe how `cosign` attaches SBOM (Software Bill of Materials) documents to containers. - -The goal is to specify the behavior well enough to promote other implementations and enable interoperability. -SBOMs attached with `cosign` should be retrievable in other tools, and vice-versa. - -This document focuses on the layout of an SBOM within an [OCI Image Manifest V1](https://github.com/opencontainers/image-spec/blob/master/manifest.md) object. - -This document does not prescribe any specific SBOM format. -Multiple formats can be used, and the `mediaType` property should describe the format of a particular SBOM document. - -Multiple SBOMs may be "attached" to one image. -Each SBOM may refer to the entire image, or to a specific part of that image. -Exactly what the SBOM refers to is called the "scope" of that SBOM. - -SBOMs stored in an OCI registry are generally assumed to refer to other objects stored in that same registry. -This document does not specify how these "links" are created. -A naming convention or the [in-progress OCI `references` API](https://github.com/opencontainers/image-spec/issues/827) are viable options. - -This document does not specify how clients should behave when multiple SBOMs are present for an image. -Clients may list all the SBOMs, or may provide tooling to filter based on SBOM type or scope. - -## Overall Layout - -An SBOM object is represented an [OCI Image Manifest V1](https://github.com/opencontainers/image-spec/blob/master/manifest.md). - -Each individual SBOM is represented as a `layer`, using a standard `descriptor`. -The `layers` list is ordered, but no order is assumed or important for the SBOM documents. - -Here is an example manifest containing one SBOM, in the [SPDX](https://spdx.org) format: - -```json -{ - "schemaVersion": 2, - "config": { - "mediaType": "application/vnd.oci.image.config.v1+json", - "size": 233, - "digest": "sha256:83bd5fb5b39f65f28e50a86d48fa79c07880befc292d92eebdc18531054b070c" - }, - "layers": [ - { - "mediaType": "text/spdx", - "size": 246, - "digest": "sha256:ed3ad03d3b87843b5419d7dce9d50a3e0f45554b2ba93bf378611cae6b450cff", - } - ] -} -``` - -Multiple SBOMs may be attached, using multiple formats. -This example shows two SBOMs, one in the SPDX format and one in the [CycloneDX](https://cyclonedx.org) format: - -```json -{ - "schemaVersion": 2, - "config": { - "mediaType": "application/vnd.oci.image.config.v1+json", - "size": 233, - "digest": "sha256:83bd5fb5b39f65f28e50a86d48fa79c07880befc292d92eebdc18531054b070c" - }, - "layers": [ - { - "mediaType": "text/spdx", - "size": 246, - "digest": "sha256:ed3ad03d3b87843b5419d7dce9d50a3e0f45554b2ba93bf378611cae6b450cff", - }, - { - "mediaType": "application/vnd.cyclonedx", - "size": 462, - "digest": "sha256:e0851a4aa13657fc8dcd01e0e5e08cb817123ccb82e2c604b34f9ec9c1755e3f", - } - ] -} -``` - -Each individual SBOM may also be "scoped" to a part of the object it refers to. -This is indicated via an annotation on the descriptor. -In this example, the SBOM only refers to a single layer: - -```json -{ - "schemaVersion": 2, - "config": { - "mediaType": "application/vnd.oci.image.config.v1+json", - "size": 233, - "digest": "sha256:83bd5fb5b39f65f28e50a86d48fa79c07880befc292d92eebdc18531054b070c" - }, - "layers": [ - { - "mediaType": "text/spdx", - "size": 246, - "digest": "sha256:ed3ad03d3b87843b5419d7dce9d50a3e0f45554b2ba93bf378611cae6b450cff", - "annotations": { - "dev.sigstore.sbom.scope": "layer=sha256:a69d803ab2179a570eda27135989ee850de53bbd98efc8f0284f13700a94149f", - } - } - ] -} -``` - -## MediaTypes - -The SBOM formats supported by cosign are [SPDX](https://spdx.org), [CycloneDX](https://cyclonedx.org/) and [syft](https://github.com/anchore/syft). -The `mediaTypes` for these should be indicated in the `descriptor` for each `layer`. - -The `mediaTypes` are: - -* `application/vnd.cyclonedx` -* `text/spdx` -* `application/vnd.syft+json` (`syft` is a JSON only format) - -These `mediaTypes` can contain format-specific suffixes as well. For example: - -* `application/vnd.cyclonedx+xml` -* `application/vnd.cyclonedx+json` -* `text/spdx+xml` -* `text/spdx+json` - -## Scopes - -SBOMs may refer to an entire object, or to a specific part of that object. -This is called the `scope` of the SBOM. - -The `scope` should be indicated via an annotation on the `Descriptor`, with the key of `dev.sigstore.sbom.scope`. - -A descriptor with no scope is assumed to refer to the entire object. -This is the same as the scope of `all`. - -Well-known scopes include: - -* `all`: the SBOM refers to the entire object. -* `layer=sha256:$DIGEST`: the SBOM refers to the layer with the appropriate digest. -* `path=`: the SBOM refers to file at path `foo` in the flattened image. - -Scopes may be repeated, and are separated by the `,` character. -This scope refers to two layers: `layer=sha256:$DIGEST,layer=sha256:$OTHERDIGEST` - -## Relationship - -While SBOMs typically relate directly to the contents of the object they refer to, in certain circumstances they may instead relate to the object indirectly. -One example here is that the SBOM could describe the environment the object was built in, rather than the contents of the object itself. -This type of relationship will be tracked by this spec somehow, but we're not sure exactly how yet. diff --git a/specs/SIGNATURE_SPEC.md b/specs/SIGNATURE_SPEC.md deleted file mode 100644 index df3ede82e..000000000 --- a/specs/SIGNATURE_SPEC.md +++ /dev/null @@ -1,399 +0,0 @@ -# Cosign Signature Specifications - -This document aims to describe how `cosign` signs containers. -The goal is to specify the behavior well enough to promote other implementations and enable interoperability. -Container signatures generated with `cosign` should be verifiable in other tools, and vice-versa. - -This document is broken up into a few parts: -* [Properties](#properties) details the individual components that are used to create and verify signatures. -* [Storage](#storage) details how signatures are stored and discovered in an OCI registry. -* [Payload](#payload) details the format of to-be-signed payloads. -* [Signature](#signature) details the signature schemes supported. - -## Properties - -This section describes the REQUIRED and OPTIONAL properties used to sign and verify an image. -Their layout in an OCI object is described below. - -* `payload` bytes - - This REQUIRED property contains the contents of signed data in byte-form. - Because signatures are __detached__, the payload MUST contain the digest of the image it references, in a well-known location. - This location is dependent on the [payload format](#payloads). - -* `mediaType` string - - This REQUIRED property contains the media type of the payload. - -* `signature` string - - This REQUIRED property contains the base64-encoded signature. - This signature MUST be generated by a supported scheme. - For more details on supported schemes, see the [`Signature`](#signature) section below. - - Example `signature`: - `MEYCIQDXmXWj59naoPFlLnCADIPLKgLG3LyFtKrbjpnkYiGNGgIhAJ/eNx5zr/l1MJKSFpFMjPKKr4fjh5RHEtT2DhMamZuT` - -* `certificate` string - - This OPTIONAL property contains a [PEM-encoded](https://en.wikipedia.org/wiki/Privacy-Enhanced_Mail) x509 certificate. - If present, this certificate MUST embed the public key that can be used to verify the signature. - - Example `certificate`: - -``` ------BEGIN CERTIFICATE----- -MIICrjCCAjSgAwIBAgIUAM4mURWUSkg06fmHmFfTmerYKaUwCgYIKoZIzj0EAwMw -KjEVMBMGA1UEChMMc2lnc3RvcmUuZGV2MREwDwYDVQQDEwhzaWdzdG9yZTAeFw0y -MTA0MDExNTU5MDZaFw0yMTA0MDExNjE4NTlaMDoxGzAZBgNVBAoMEmRsb3JlbmNA -Z29vZ2xlLmNvbTEbMBkGA1UEAwwSZGxvcmVuY0Bnb29nbGUuY29tMFkwEwYHKoZI -zj0CAQYIKoZIzj0DAQcDQgAE3R0ZtpfBd3Y8DaXuB1gM8JPlhsDIEfXO/WsMJEN1 -4hEn8wajX2HklqL7igZPFICv6tBUGylIHp2mTH2Nhv38mqOCASYwggEiMA4GA1Ud -DwEB/wQEAwIHgDATBgNVHSUEDDAKBggrBgEFBQcDAzAMBgNVHRMBAf8EAjAAMB0G -A1UdDgQWBBTy3UWIop0bNrdNgSrVHHD10qSASTAfBgNVHSMEGDAWgBTIxR0AQZok -KTJRJOsNrkrtSgbT7DCBjQYIKwYBBQUHAQEEgYAwfjB8BggrBgEFBQcwAoZwaHR0 -cDovL3ByaXZhdGVjYS1jb250ZW50LTYwM2ZlN2U3LTAwMDAtMjIyNy1iZjc1LWY0 -ZjVlODBkMjk1NC5zdG9yYWdlLmdvb2dsZWFwaXMuY29tL2NhMzZhMWU5NjI0MmI5 -ZmNiMTQ2L2NhLmNydDAdBgNVHREEFjAUgRJkbG9yZW5jQGdvb2dsZS5jb20wCgYI -KoZIzj0EAwMDaAAwZQIwC15Gtd9F6W9lmJuoXMym9DfWlBpK5HEPak38WPXqowRp -6p+2/3jSLkFT5Nn5fuISAjEAouVlX4zH2rlkfg45HnDJax7o6ZV+E0/6BdAms44D -Ej6T/GLK6XJSB28haSPRWB7k ------END CERTIFICATE----- -``` - -* `chain` string - This OPTIONAL property contains a PEM-encoded, DER-formatted, ASN.1 x509 certificate chain. - The `certificate` property MUST be present if this property is present. - This chain MAY be used by implementations to verify the `certificate` property. - - Example `chain`: - -``` -----BEGIN CERTIFICATE----- -MIIB+DCCAX6gAwIBAgITNVkDZoCiofPDsy7dfm6geLbuhzAKBggqhkjOPQQDAzAq -MRUwEwYDVQQKEwxzaWdzdG9yZS5kZXYxETAPBgNVBAMTCHNpZ3N0b3JlMB4XDTIx -MDMwNzAzMjAyOVoXDTMxMDIyMzAzMjAyOVowKjEVMBMGA1UEChMMc2lnc3RvcmUu -ZGV2MREwDwYDVQQDEwhzaWdzdG9yZTB2MBAGByqGSM49AgEGBSuBBAAiA2IABLSy -A7Ii5k+pNO8ZEWY0ylemWDowOkNa3kL+GZE5Z5GWehL9/A9bRNA3RbrsZ5i0Jcas -taRL7Sp5fp/jD5dxqc/UdTVnlvS16an+2Yfswe/QuLolRUCrcOE2+2iA5+tzd6Nm -MGQwDgYDVR0PAQH/BAQDAgEGMBIGA1UdEwEB/wQIMAYBAf8CAQEwHQYDVR0OBBYE -FMjFHQBBmiQpMlEk6w2uSu1KBtPsMB8GA1UdIwQYMBaAFMjFHQBBmiQpMlEk6w2u -Su1KBtPsMAoGCCqGSM49BAMDA2gAMGUCMH8liWJfMui6vXXBhjDgY4MwslmN/TJx -Ve/83WrFomwmNf056y1X48F9c4m3a3ozXAIxAKjRay5/aj/jsKKGIkmQatjI8uup -Hr/+CxFvaJWmpYqNkLDGRU+9orzh5hI2RrcuaQ== ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIICVTCCAT2gAwIBAgIQAUrAOaxMcCVQ6AwcDagmRzANBgkqhkiG9w0BAQsFADAh -MR8wHQYDVQQDDBZZdWJpY28gUElWIEF0dGVzdGF0aW9uMCAXDTE2MDMxNDAwMDAw -MFoYDzIwNTIwNDE3MDAwMDAwWjAlMSMwIQYDVQQDDBpZdWJpS2V5IFBJViBBdHRl -c3RhdGlvbiA5YzBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABFfnSOVAZLOTOYRs -n4BeD3cMYHFvtwBsK8X0yJ21NKUwJ3fvnqdq0qGeIT92zstNLEWCqP3qMkhs9sh4 -wP1tHTGjTjBMMBEGCisGAQQBgsQKAwMEAwUCBjAUBgorBgEEAYLECgMHBAYCBADH -kP4wEAYKKwYBBAGCxAoDCAQCAwIwDwYKKwYBBAGCxAoDCQQBAzANBgkqhkiG9w0B -AQsFAAOCAQEAVRtRFpmgFD+rQqBG92HArMQ+j1FMX23QL9Z76IhaSElmN6cjgsv3 -8pJM8GL+ih6vVyCHeU6GoE9Bgj2XB02ZgkmWihnaJX2WG4VOm2dN3SqDmWFp4KLJ -vuzVXEHWuGevwMAOsvMkmXP8HI2npaCPBmprirExbv6bxSyng4ZNHmgdzqmjYyt+ -d+ELe3xEeYYqQYx+IswHPRE5mGk/PO4hysk79mhwRNuvmygDbI8Emwvp3Pgzlgr1 -Gyp4apdU7AXEwysEQIb034aPrTlpmxh90SnTZFs2DHOvCjCPPAmoWfuQUwPhSPRb -92pXqODWYqpW8+IRED5e42Ncu9XtDgS5Pw== ------END CERTIFICATE----- -``` - -* `bundle` string - - This OPTIONAL property contains a JSON formatted `bundle` type, which can be used for offline verification. - Example `bundle`: - -```json -{ - "SignedEntryTimestamp": "MEUCIQDHiGUesxPpn+qRONLmKlNIVPhl9gBMnwNeIQmRkRmZVQIgRxPpuYQDZR/8lYKcEfiQn5b+7VDoJIC72ZWHO9ZCp1A=", - "Payload": { - "body": "eyJhcGlWZXJzaW9uIjoiMC4wLjEiLCJzcGVjIjp7ImRhdGEiOnsiaGFzaCI6eyJhbGdvcml0aG0iOiJzaGEyNTYiLCJ2YWx1ZSI6ImE0NDkyYjBlYWJkZDIzMTJmMDYzMjkwYWJkNzk3ZDlkNzFhM2FiMjhiZDY1YTJjMTg5YjBkZjBkMzliOGMzYjkifX0sInNpZ25hdHVyZSI6eyJjb250ZW50IjoiTUVRQ0lDTmRYeTNiWHAxRE1PTDZOUGZYMzVnSjI3YnpsZHdTdkNBTnd5ZE9RVWlqQWlCQWg5WlJwQ3AzYlg5eE9UbEhTR2w0cFVGd0ZtUFJJWGZpY09pRTBHM1Vzdz09IiwiZm9ybWF0IjoieDUwOSIsInB1YmxpY0tleSI6eyJjb250ZW50IjoiTFMwdExTMUNSVWRKVGlCRFJWSlVTVVpKUTBGVVJTMHRMUzB0Q2sxSlNVTmxla05EUVdkRFowRjNTVUpCWjBsVVZISk9aa013YkZSSmRWSXZWR0UyWm14MWFtdFFOWHBaTDFSQlMwSm5aM0ZvYTJwUFVGRlJSRUY2UVhFS1RWSlZkMFYzV1VSV1VWRkxSWGQ0ZW1GWFpIcGtSemw1V2xNMWExcFlXWGhGVkVGUVFtZE9Wa0pCVFZSRFNFNXdXak5PTUdJelNteE5RalJZUkZSSmVBcE5SRmw1VFdwSmVFMUVaM2RPUm05WVJGUkplRTFFV1hsTmFrbDRUV3BuZDAweGIzZEJSRUphVFVKTlIwSjVjVWRUVFRRNVFXZEZSME5EY1VkVFRUUTVDa0YzUlVoQk1FbEJRazFGV1M4ck4yRktjRmRLVFhjNWVrTmljMDFrT0hOQlRUTmxSbk5OTjBSbFpFZGlXRzlNUjJ4YUwyZHBNR2h5WTBaU1NWVTRiM2NLUzBKeU1ISkVTRE5QVkZaSWJVdFVZMkV2SzIweGQxQjNTVzlZTTFGUVYycG5aMFYwVFVsSlFrdFVRVTlDWjA1V1NGRTRRa0ZtT0VWQ1FVMURRalJCZHdwRmQxbEVWbEl3YkVKQmQzZERaMWxKUzNkWlFrSlJWVWhCZDAxM1JFRlpSRlpTTUZSQlVVZ3ZRa0ZKZDBGRVFXUkNaMDVXU0ZFMFJVWm5VVlZ5WVRoTENuSnJaMjAzVGtsNFRrNXBVMkpZVG00eFdFVkxhRzFyZDBoM1dVUldVakJxUWtKbmQwWnZRVlY1VFZWa1FVVkhZVXBEYTNsVlUxUnlSR0UxU3pkVmIwY0tNQ3QzZDJkWk1FZERRM05IUVZGVlJrSjNSVUpDU1VkQlRVZzBkMlpCV1VsTGQxbENRbEZWU0UxQlMwZGpSMmd3WkVoQk5reDVPWGRqYld3eVdWaFNiQXBaTWtWMFdUSTVkV1JIVm5Wa1F6QXlUVVJPYlZwVVpHeE9lVEIzVFVSQmQweFVTWGxOYW1OMFdXMVpNMDVUTVcxT1Ixa3hXbFJuZDFwRVNUVk9WRkYxQ21NelVuWmpiVVp1V2xNMWJtSXlPVzVpUjFab1kwZHNla3h0VG5aaVV6bHFXVlJOTWxsVVJteFBWRmw1VGtSS2FVOVhXbXBaYWtVd1RtazVhbGxUTldvS1kyNVJkMHBCV1VSV1VqQlNRVkZJTDBKQ2IzZEhTVVZYWTBoS2NHVlhSak5aVjFKdlpESkdRVm95T1haYU1uaHNURzFPZG1KVVFVdENaMmR4YUd0cVR3cFFVVkZFUVhkT2NFRkVRbTFCYWtWQk1UQlVSR015Wm1oUFZrRlVNWFJzZFM4MmMzWnhSbEZ1YkRaWU9YZGhNbXRUU2t0RGJqUkZZbFJFYTNwYVJYb3lDblppUWtwb2FFZ3ZjbWRXUjFKMU5tWkJha1ZCYkhsb05uUmhZelJZVFRaS2IzVlZlRWtyTjFnelFtUTFXVXR5WlRGS1dFOWhia0ZaYW1adldHNTVUSFFLZDNCSVFWb3paVzFhY0VWa00yeHFTVEF3Vm04S0xTMHRMUzFGVGtRZ1EwVlNWRWxHU1VOQlZFVXRMUzB0TFFvPSJ9fX0sImtpbmQiOiJyZWtvcmQifQ==", - "integratedTime": 1624396085, - "logIndex": 5179, - "logID": "c0d23d6ad406973f9559f3ba2d1ca01f84147d8ffc5b8445c224f98b9591801d" - } -} -``` - The following are REQUIRED properties of the bundle: - - The `SignedEntryTimestamp` is a rekor-signed signature over the logIndex, body and integratedTime of the Rekor Log Entry - - The `Payload` consists of all fields required to verify the SET: - - The `body` is the body of the Rekor Log Entry - - The `integratedTime` is the UNIX timestamp the log entry was integrated into the transparency log - - The `logIndex` is the index of the log entry in the transparency log - - The `logID` is the SHA256 hash of the DER-encoded public key for the log at the time the entry was included in the log - -For instructions on using the `bundle` for verification, see [USAGE.md](../USAGE.md#verify-a-signature-was-added-to-the-transparency-log). - -## Storage - -`cosign` image signatures are stored in an OCI registry and are designed to make use of the existing specifications. -The full specifications for the OCI formats and specifications used are available [here](https://github.com/opencontainers). - -### Discovery - -Signature object are placed in specific location in an OCI registry to enable consistent, interoperable discovery. - -Multiple discovery mechanisms MAY be used. -Implementations MUST support at least the following mechanisms: - -* Tag-based Discovery - -#### Tag-based Discovery - -In this scheme, signatures are stored in an OCI registry in a predictable location, addressable by tag. -The location of signatures corresponding to a specific object can be computed using the digest of the object. - -If the object is referenced by tag, the tag must first be resolved to a digest. -Then the digest of the object (of the form `sha256:abcdef...`) is encoded into a tag name using the following rules: - -* Replace the `:` character with a `-` -* Append the `.sig` suffix - -Example digest->tag mapping: - -1. Start with `gcr.io/dlorenc-vmtest2/demo:latest` -2. Resolve this to a digest: `sha256:97fc222cee7991b5b061d4d4afdb5f3428fcb0c9054e1690313786befa1e4e36` -3. Follow the encoding rules: `sha256-97fc222cee7991b5b061d4d4afdb5f3428fcb0c9054e1690313786befa1e4e36.sig` -4. Signature can be found at `gcr.io/dlorenc-vmtest2/demo:sha256-97fc222cee7991b5b061d4d4afdb5f3428fcb0c9054e1690313786befa1e4e36.sig` - -Implementations MAY store signatures objects in the same OCI repository as the target image or a different one. - -### Object Types - -This section describes the way the properties from above are embedded into OCI objects that can be stored in a registry. -Implementations MUST support storing signatures in at least the following object types: - -* [OCI Image Manifest V1](#oci-image-manifest-v1) - -#### OCI Image Manifest V1 - -This section describes the way the mandatory and optional signature properties are embedded into an -[OCI Image Manifest V1](https://github.com/opencontainers/image-spec/blob/master/manifest.md) object. - -Only one image manifest is created for every signed object. -Multiple signatures can be embedded in one image manifest. - -##### Payload and mediaType - -The `payload` bytes are uploaded to an OCI registry as a `blob`, and are referenced by `digest`, `size` and `mediaType.` -The digest is embedded into the `Image` manifest as a `layer`, via a [`Descriptor`](https://github.com/opencontainers/image-spec/blob/master/descriptor.md). - -The `mediaType` property for the `payload` is included in the same descriptor. - -Example `payload`: - -```json -{ - "schemaVersion": 2, - "config": { - "mediaType": "application/vnd.oci.image.config.v1+json", - - }, - "layers": [ - { - "mediaType": "application/vnd.dev.cosign.simplesigning.v1+json", - "size": 210, - "digest": "sha256:1119abab63e605dcc281019bad0424744178b6f61ba57378701fe7391994c999", - }, - - ] -} -``` - -##### Signature - -The `signature` is base64-encoded and stored as an `annotation` on the layer, in the same descriptor. -The `annotation` key is `dev.cosignproject.cosign/signature`. - -Example `signature`: - -```json -"annotations": { - "dev.cosignproject.cosign/signature": "MEUCIBKI9FIC+YD3m/lWViyPxsJsbnIHj86sSbb7L3qvpEFoAiEA2ZChO/67CuAPQKJLBVsAc7bs9hBK8RpsdfjBsByGKJM=" -} -``` - -##### Certificate - -The `certificate` is stored as an `annotation` on the layer, in the same descriptor. -The `annotation` key is `dev.cosignproject.cosign/certificate`. - -Example `certificate`: - -```json -"annotations": { - "dev.sigstore.cosign/certificate": "-----BEGIN CERTIFICATE-----\nMIICrjCCAjSgAwIBAgIUAM4mURWUSkg06fmHmFfTmerYKaUwCgYIKoZIzj0EAwMw\nKjEVMBMGA1UEChMMc2lnc3RvcmUuZGV2MREwDwYDVQQDEwhzaWdzdG9yZTAeFw0y\nMTA0MDExNTU5MDZaFw0yMTA0MDExNjE4NTlaMDoxGzAZBgNVBAoMEmRsb3JlbmNA\nZ29vZ2xlLmNvbTEbMBkGA1UEAwwSZGxvcmVuY0Bnb29nbGUuY29tMFkwEwYHKoZI\nzj0CAQYIKoZIzj0DAQcDQgAE3R0ZtpfBd3Y8DaXuB1gM8JPlhsDIEfXO/WsMJEN1\n4hEn8wajX2HklqL7igZPFICv6tBUGylIHp2mTH2Nhv38mqOCASYwggEiMA4GA1Ud\nDwEB/wQEAwIHgDATBgNVHSUEDDAKBggrBgEFBQcDAzAMBgNVHRMBAf8EAjAAMB0G\nA1UdDgQWBBTy3UWIop0bNrdNgSrVHHD10qSASTAfBgNVHSMEGDAWgBTIxR0AQZok\nKTJRJOsNrkrtSgbT7DCBjQYIKwYBBQUHAQEEgYAwfjB8BggrBgEFBQcwAoZwaHR0\ncDovL3ByaXZhdGVjYS1jb250ZW50LTYwM2ZlN2U3LTAwMDAtMjIyNy1iZjc1LWY0\nZjVlODBkMjk1NC5zdG9yYWdlLmdvb2dsZWFwaXMuY29tL2NhMzZhMWU5NjI0MmI5\nZmNiMTQ2L2NhLmNydDAdBgNVHREEFjAUgRJkbG9yZW5jQGdvb2dsZS5jb20wCgYI\nKoZIzj0EAwMDaAAwZQIwC15Gtd9F6W9lmJuoXMym9DfWlBpK5HEPak38WPXqowRp\n6p+2/3jSLkFT5Nn5fuISAjEAouVlX4zH2rlkfg45HnDJax7o6ZV+E0/6BdAms44D\nEj6T/GLK6XJSB28haSPRWB7k\n-----END CERTIFICATE-----\n", -} -``` - -##### Chain - -The `chain` is stored as an `annotation` on the layer, in the same descriptor. -The `annotation` key is `dev.cosignproject.cosign/chain`. - -Example `chain`: - -```json -"annotations": { - "dev.sigstore.cosign/chain": "-----BEGIN CERTIFICATE-----\nMIIB+DCCAX6gAwIBAgITNVkDZoCiofPDsy7dfm6geLbuhzAKBggqhkjOPQQDAzAq\nMRUwEwYDVQQKEwxzaWdzdG9yZS5kZXYxETAPBgNVBAMTCHNpZ3N0b3JlMB4XDTIx\nMDMwNzAzMjAyOVoXDTMxMDIyMzAzMjAyOVowKjEVMBMGA1UEChMMc2lnc3RvcmUu\nZGV2MREwDwYDVQQDEwhzaWdzdG9yZTB2MBAGByqGSM49AgEGBSuBBAAiA2IABLSy\nA7Ii5k+pNO8ZEWY0ylemWDowOkNa3kL+GZE5Z5GWehL9/A9bRNA3RbrsZ5i0Jcas\ntaRL7Sp5fp/jD5dxqc/UdTVnlvS16an+2Yfswe/QuLolRUCrcOE2+2iA5+tzd6Nm\nMGQwDgYDVR0PAQH/BAQDAgEGMBIGA1UdEwEB/wQIMAYBAf8CAQEwHQYDVR0OBBYE\nFMjFHQBBmiQpMlEk6w2uSu1KBtPsMB8GA1UdIwQYMBaAFMjFHQBBmiQpMlEk6w2u\nSu1KBtPsMAoGCCqGSM49BAMDA2gAMGUCMH8liWJfMui6vXXBhjDgY4MwslmN/TJx\nVe/83WrFomwmNf056y1X48F9c4m3a3ozXAIxAKjRay5/aj/jsKKGIkmQatjI8uup\nHr/+CxFvaJWmpYqNkLDGRU+9orzh5hI2RrcuaQ==\n-----END CERTIFICATE-----" -} -``` - -## Payloads - -Implementations MUST support at least the following payload types: - - * Simple Signing - -### Simple Signing - -The Simple Signing payload format is [specified here](https://github.com/containers/image/blob/a5061e5a5f00333ea3a92e7103effd11c6e2f51d/docs/containers-signature.5.md#json-data-format) - -The following additional semantics are applied: - -* The `mediaType` used to identify this payload format is: `application/vnd.dev.cosign.simplesigning.v1+json`. -* The `critical.type` value used to identify `cosign` signatures is: `cosign container image signature`. -* The `critical.identity.docker-reference` field is ignored. -* Optional user-specified claims may be included in the `Optional` section. - -For example: -```json -{ - "critical": { - "identity": { - "docker-reference": "testing/manifest" - }, - "image": { - "Docker-manifest-digest": "sha256:20be...fe55" - }, - "type": "cosign container image signature" - }, - "optional": { - "creator": "atomic", - "timestamp": 1458239713 - } -} -``` - -## Signature Schemes - -Implementations must support at least the following schemes: - -* ECDSA-P256 - -No information about the signature scheme is included in the object. -Clients must determine the signature scheme out-of-band during the verification process. - -### Hashing Algorithms - -Signers and verifiers must know the hash algorithm used in addition to the signature scheme. -In an attempt to avoid specifying a particular hashing algorithm, we require that digest be calculated using the SAME algorithm as the OCI registry. -In practice, this means [sha256](https://github.com/opencontainers/image-spec/blob/master/descriptor.md#digests). - -When the payload is stored as a `blob` in the OCI registry, it is exposed and referenced via a [Content Addressable](https://en.wikipedia.org/wiki/Content-addressable_storage) API. - -Example referenced payload: - -```json -{ - "mediaType": "application/vnd.dev.cosign.simplesigning.v1+json", - "size": 210, - "digest": "sha256:1119abab63e605dcc281019bad0424744178b6f61ba57378701fe7391994c999", -} -``` - -Here, `1119abab63e605dcc281019bad0424744178b6f61ba57378701fe7391994c999` is the hex-encoded digest, and the `sha256:` prefix specifies the algorithm. -This value is already calculated and verified by both the registry and client-tooling. - -This means that our signatures is "linked" to a "container image" happens via two hops: - -`Sign(sha256(SimpleSigningPayload(sha256(Image Manifest))))` - -Allowing flexibility in hashing algorithms of the digital signature would only allow manipulation of the "outer" one - the image manifest -itself is always referenced by `sha256` today. -This means using a different hashing algorithm as part of the final signature, even one perceived as "stronger", would result in limited cryptographic benefits. - -Put simply: implementations MUST use the same hash algorithm used by the underlying registry to reference the payload. -Any future algorithmic-agility will come from the storage layer as part of the OCI specification. - -# Rationales and Commentary - -This document, while labeled a `Specification`, aims to specify as few things as possible. -Instead, we prescribe the usage of other specifications. - -This section contains a rationale for each choice, as well as comparisons to alternatives considered. - -## Payload/Attestation Format: Simple Signing - -We chose Simple Signing because it has the most existing usage and meets our requirements: - -* Critical/Optional sections -* Extensible with more attestations -* Cross-language serialization support - -### Alternatives - -* OCI Descriptor. - - This has the fields we need, with a few problems. - * The annotations section is limiting with map[string]string. - * The `URLs` field is not meant for this use-case. - * No real benefit, since it's stored as a `blob` (not parsed by the registry). - -* Plain digest - - This doesn't have any attestation/annotation support. - -* Something new - - See above, we've tried to avoid making any new types where possible. - -## OCI Type - Docker Manifest/OCI Manifest - -We're currently using Docker but will switch to OCI. -The format support across registries is a toss-up, but likely to improve for OCI. -OCI supports custom media-types and has other "correctness" benefits. - -## Discovery - Tag Based - -We use the tag based mechanism because it's the only option we can think of. -It meets the two hard requirements: works **everywhere** today and requires no extra services. -It also does not mutate the signed object (like an attached signature or index might). - -Support for multiple signatures works but is racy. - -### Alternatives Considered - -Notary v1/Grafeas both require another database. -A few other proprietary APIs exist, but they're not cross-registry. - -## Hash Algorithm - None! - -Most common signature schemes support customizable hash algorithms. -These are typically stored with the signature for convenience, presenting a possible attack/confusion vector. - -We decided to pin to the registry hash algorithm. -This removes an entire moving part without sacrificing agility. - -The registry/client-tooling already perform hash validation as part of the CAS. -While their spec does not completely pin to specific algorithm, SHA256 is ubiquitous in practice. -This means that our signed payload object references the actual image "target" by a sha-256 digest - the entire signature already relies on the strength of this algorithm. - -Trading off this perceived agility for the reduction in attack surface is a win. - -** Note **: This is only possible if we store the `payload` in a blob by itself. -Serializing the payload and signature together in something like a JWT for storage would mean the payload is no longer directly hashed into the CAS. -There is also a performance benefit: we can validate the signature (stored in the manifest) against the payload (stored as a blob) without fetching the blob, because the blob's digest is also present in the manifest. - -## Algorithms - -We only require ECDSA-P256 (with the SHA256 hash algorithm, see above), but will allow for other schemes. -We will bias toward algorithms well-supported in the Go ecosystem, but will accept others. -We will bias toward support for algorithms with wide industry adoption, API support, and hardware availability. - -## Compatibility - -We are compatible with the In-Toto [Metablock](https://in-toto.readthedocs.io/en/latest/model.html) and JWS [rfc7515](https://tools.ietf.org/html/rfc7515) formats. -This means we can convert to these formats during verification, and from these formats during upload/signature. -You can think of this spec as an "on-registry serialization format" for either of these specified formats. diff --git a/third_party/VENDOR-LICENSE/github.com/cpuguy83/go-md2man/v2/md2man/LICENSE.md b/third_party/VENDOR-LICENSE/github.com/cpuguy83/go-md2man/v2/md2man/LICENSE.md deleted file mode 100644 index 1cade6cef..000000000 --- a/third_party/VENDOR-LICENSE/github.com/cpuguy83/go-md2man/v2/md2man/LICENSE.md +++ /dev/null @@ -1,21 +0,0 @@ -The MIT License (MIT) - -Copyright (c) 2014 Brian Goff - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. diff --git a/third_party/VENDOR-LICENSE/github.com/russross/blackfriday/v2/LICENSE.txt b/third_party/VENDOR-LICENSE/github.com/russross/blackfriday/v2/LICENSE.txt deleted file mode 100644 index 2885af360..000000000 --- a/third_party/VENDOR-LICENSE/github.com/russross/blackfriday/v2/LICENSE.txt +++ /dev/null @@ -1,29 +0,0 @@ -Blackfriday is distributed under the Simplified BSD License: - -> Copyright © 2011 Russ Ross -> All rights reserved. -> -> Redistribution and use in source and binary forms, with or without -> modification, are permitted provided that the following conditions -> are met: -> -> 1. Redistributions of source code must retain the above copyright -> notice, this list of conditions and the following disclaimer. -> -> 2. Redistributions in binary form must reproduce the above -> copyright notice, this list of conditions and the following -> disclaimer in the documentation and/or other materials provided with -> the distribution. -> -> THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -> "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -> LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS -> FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE -> COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, -> INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, -> BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -> LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -> CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -> LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN -> ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -> POSSIBILITY OF SUCH DAMAGE. diff --git a/third_party/VENDOR-LICENSE/github.com/withfig/autocomplete-tools/packages/cobra/LICENSE b/third_party/VENDOR-LICENSE/github.com/withfig/autocomplete-tools/packages/cobra/LICENSE deleted file mode 100644 index 42251ea84..000000000 --- a/third_party/VENDOR-LICENSE/github.com/withfig/autocomplete-tools/packages/cobra/LICENSE +++ /dev/null @@ -1,21 +0,0 @@ -MIT License - -Copyright (c) 2021 Hercules Labs Inc. (Fig) - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. From 3c82a9ec88e052afb7cfbf19a510667c68220899 Mon Sep 17 00:00:00 2001 From: Ville Aikas Date: Thu, 9 Jun 2022 11:46:02 +0300 Subject: [PATCH 2/2] Remove docgen gha. Signed-off-by: Ville Aikas --- .github/workflows/verify-docgen.yaml | 39 ---------------------------- 1 file changed, 39 deletions(-) delete mode 100644 .github/workflows/verify-docgen.yaml diff --git a/.github/workflows/verify-docgen.yaml b/.github/workflows/verify-docgen.yaml deleted file mode 100644 index 2e1631152..000000000 --- a/.github/workflows/verify-docgen.yaml +++ /dev/null @@ -1,39 +0,0 @@ -# -# Copyright 2021 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. - -name: Docgen - -on: - workflow_dispatch: - push: - branches: ['main', 'release-*'] - pull_request: - -permissions: read-all - -jobs: - docgen: - name: Verify Docgen - runs-on: ubuntu-latest - - steps: - - name: deps - run: sudo apt-get update && sudo apt-get install -yq libpcsclite-dev - - uses: actions/checkout@2541b1294d2704b0964813337f33b291d3f8596b # v2.4.0 - - uses: actions/setup-go@b22fbbc2921299758641fab08929b4ac52b32923 # v2.2.0 - with: - go-version: '1.17' - check-latest: true - - run: ./cmd/help/verify.sh