Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: cert-extensions verify #1626

Merged
merged 1 commit into from
Jun 29, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
33 changes: 19 additions & 14 deletions cmd/cosign/cli/dockerfile.go
Original file line number Diff line number Diff line change
Expand Up @@ -85,20 +85,25 @@ Shell-like variables in the Dockerfile's FROM lines will be substituted with val
}
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,
RegistryOptions: o.Registry,
CheckClaims: o.CheckClaims,
KeyRef: o.Key,
CertRef: o.CertVerify.Cert,
CertEmail: o.CertVerify.CertEmail,
CertOidcIssuer: o.CertVerify.CertOidcIssuer,
CertGithubWorkflowTrigger: o.CertVerify.CertGithubWorkflowTrigger,
CertGithubWorkflowSha: o.CertVerify.CertGithubWorkflowSha,
CertGithubWorkflowName: o.CertVerify.CertGithubWorkflowName,
CertGithubWorkflowRepository: o.CertVerify.CertGithubWorkflowRepository,
CertGithubWorkflowRef: o.CertVerify.CertGithubWorkflowRef,
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,
}
Expand Down
33 changes: 19 additions & 14 deletions cmd/cosign/cli/manifest.go
Original file line number Diff line number Diff line change
Expand Up @@ -80,20 +80,25 @@ against the transparency log.`,
}
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,
RegistryOptions: o.Registry,
CheckClaims: o.CheckClaims,
KeyRef: o.Key,
CertRef: o.CertVerify.Cert,
CertEmail: o.CertVerify.CertEmail,
CertOidcIssuer: o.CertVerify.CertOidcIssuer,
CertGithubWorkflowTrigger: o.CertVerify.CertGithubWorkflowTrigger,
CertGithubWorkflowSha: o.CertVerify.CertGithubWorkflowSha,
CertGithubWorkflowName: o.CertVerify.CertGithubWorkflowName,
CertGithubWorkflowRepository: o.CertVerify.CertGithubWorkflowRepository,
CertGithubWorkflowRef: o.CertVerify.CertGithubWorkflowRef,
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)
Expand Down
32 changes: 27 additions & 5 deletions cmd/cosign/cli/options/certificate.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,11 +20,16 @@ import (

// CertVerifyOptions is the wrapper for certificate verification.
type CertVerifyOptions struct {
Cert string
CertEmail string
CertOidcIssuer string
CertChain string
EnforceSCT bool
Cert string
CertEmail string
CertOidcIssuer string
CertGithubWorkflowTrigger string
CertGithubWorkflowSha string
CertGithubWorkflowName string
CertGithubWorkflowRepository string
CertGithubWorkflowRef string
CertChain string
EnforceSCT bool
}

var _ Interface = (*RekorOptions)(nil)
Expand All @@ -40,6 +45,23 @@ func (o *CertVerifyOptions) AddFlags(cmd *cobra.Command) {
cmd.Flags().StringVar(&o.CertOidcIssuer, "certificate-oidc-issuer", "",
"the OIDC issuer expected in a valid Fulcio certificate, e.g. https://token.actions.githubusercontent.com or https://oauth2.sigstore.dev/auth")

// -- Cert extensions begin --
// Source: https://github.com/sigstore/fulcio/blob/main/docs/oid-info.md
cmd.Flags().StringVar(&o.CertGithubWorkflowTrigger, "certificate-github-workflow-trigger", "",
"contains the event_name claim from the GitHub OIDC Identity token that contains the name of the event that triggered the workflow run")

cmd.Flags().StringVar(&o.CertGithubWorkflowSha, "certificate-github-workflow-sha", "",
"contains the sha claim from the GitHub OIDC Identity token that contains the commit SHA that the workflow run was based upon.")

cmd.Flags().StringVar(&o.CertGithubWorkflowName, "certificate-github-workflow-name", "",
"contains the workflow claim from the GitHub OIDC Identity token that contains the name of the executed workflow.")

cmd.Flags().StringVar(&o.CertGithubWorkflowRepository, "certificate-github-workflow-repository", "",
"contains the repository claim from the GitHub OIDC Identity token that contains the repository that the workflow run was based upon")

cmd.Flags().StringVar(&o.CertGithubWorkflowRef, "certificate-github-workflow-ref", "",
"contains the ref claim from the GitHub OIDC Identity token that contains the git ref that the workflow run was based upon.")
// -- Cert extensions end --
cmd.Flags().StringVar(&o.CertChain, "certificate-chain", "",
"path to a list of CA certificates in PEM format which will be needed "+
"when building the certificate chain for the signing certificate. "+
Expand Down
3 changes: 2 additions & 1 deletion cmd/cosign/cli/policy_init.go
Original file line number Diff line number Diff line change
Expand Up @@ -202,7 +202,8 @@ func signPolicy() *cobra.Command {
return errors.New("error decoding certificate")
}
signerEmail := sigs.CertSubject(certs[0])
signerIssuer := sigs.CertIssuerExtension(certs[0])
ce := cosign.CertExtensions{Cert: certs[0]}
signerIssuer := ce.GetIssuer()

// Retrieve root.json from registry.
imgName := rootPath(o.ImageRef)
Expand Down
78 changes: 45 additions & 33 deletions cmd/cosign/cli/verify.go
Original file line number Diff line number Diff line change
Expand Up @@ -93,23 +93,28 @@ against the transparency log.`,
}

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,
RegistryOptions: o.Registry,
CheckClaims: o.CheckClaims,
KeyRef: o.Key,
CertRef: o.CertVerify.Cert,
CertEmail: o.CertVerify.CertEmail,
CertOidcIssuer: o.CertVerify.CertOidcIssuer,
CertGithubWorkflowTrigger: o.CertVerify.CertGithubWorkflowTrigger,
CertGithubWorkflowSha: o.CertVerify.CertGithubWorkflowSha,
CertGithubWorkflowName: o.CertVerify.CertGithubWorkflowName,
CertGithubWorkflowRepository: o.CertVerify.CertGithubWorkflowRepository,
CertGithubWorkflowRef: o.CertVerify.CertGithubWorkflowRef,
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,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also need to update VerifyAttestation with the new verify options, on line 185

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

good catch @haydentherapper as always

}

return v.Exec(cmd.Context(), args)
Expand Down Expand Up @@ -172,21 +177,26 @@ against the transparency log.`,
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,
RegistryOptions: o.Registry,
CheckClaims: o.CheckClaims,
CertRef: o.CertVerify.Cert,
CertEmail: o.CertVerify.CertEmail,
CertOidcIssuer: o.CertVerify.CertOidcIssuer,
CertChain: o.CertVerify.CertChain,
CertGithubWorkflowTrigger: o.CertVerify.CertGithubWorkflowTrigger,
CertGithubWorkflowSha: o.CertVerify.CertGithubWorkflowSha,
CertGithubWorkflowName: o.CertVerify.CertGithubWorkflowName,
CertGithubWorkflowRepository: o.CertVerify.CertGithubWorkflowRepository,
CertGithubWorkflowRef: o.CertVerify.CertGithubWorkflowRef,
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)
},
Expand Down Expand Up @@ -258,7 +268,9 @@ The blob may be specified as a path to a file or - for stdin.`,
}
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 {
o.Signature, args[0], o.CertVerify.CertGithubWorkflowTrigger, o.CertVerify.CertGithubWorkflowSha,
o.CertVerify.CertGithubWorkflowName, o.CertVerify.CertGithubWorkflowRepository, o.CertVerify.CertGithubWorkflowRef,
o.CertVerify.EnforceSCT); err != nil {
return fmt.Errorf("verifying blob %s: %w", args, err)
}
return nil
Expand Down
97 changes: 73 additions & 24 deletions cmd/cosign/cli/verify/verify.go
Original file line number Diff line number Diff line change
Expand Up @@ -48,22 +48,27 @@ import (
// nolint
Copy link
Contributor

@haydentherapper haydentherapper Jun 6, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

thank you, I missed those parts.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

thanks for updating these!

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
CheckClaims bool
KeyRef string
CertRef string
CertEmail string
CertOidcIssuer string
CertGithubWorkflowTrigger string
CertGithubWorkflowSha string
CertGithubWorkflowName string
CertGithubWorkflowRepository string
CertGithubWorkflowRef 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
Expand Down Expand Up @@ -92,12 +97,17 @@ func (c *VerifyCommand) Exec(ctx context.Context, images []string) (err error) {
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,
Annotations: c.Annotations.Annotations,
RegistryClientOpts: ociremoteOpts,
CertEmail: c.CertEmail,
CertOidcIssuer: c.CertOidcIssuer,
CertGithubWorkflowTrigger: c.CertGithubWorkflowTrigger,
CertGithubWorkflowSha: c.CertGithubWorkflowSha,
CertGithubWorkflowName: c.CertGithubWorkflowName,
CertGithubWorkflowRepository: c.CertGithubWorkflowRepository,
CertGithubWorkflowRef: c.CertGithubWorkflowRef,
EnforceSCT: c.EnforceSCT,
SignatureRef: c.SignatureRef,
}
if c.CheckClaims {
co.ClaimVerifier = cosign.SimpleClaimVerifier
Expand Down Expand Up @@ -239,10 +249,30 @@ func PrintVerification(imgRef string, verified []oci.Signature, output string) {
case "text":
for _, sig := range verified {
if cert, err := sig.Cert(); err == nil && cert != nil {
ce := cosign.CertExtensions{Cert: cert}
fmt.Fprintln(os.Stderr, "Certificate subject: ", sigs.CertSubject(cert))
if issuerURL := sigs.CertIssuerExtension(cert); issuerURL != "" {
if issuerURL := ce.GetIssuer(); issuerURL != "" {
fmt.Fprintln(os.Stderr, "Certificate issuer URL: ", issuerURL)
}

if githubWorkflowTrigger := ce.GetCertExtensionGithubWorkflowTrigger(); githubWorkflowTrigger != "" {
fmt.Fprintln(os.Stderr, "Certificate extension GitHub Workflow Trigger:", githubWorkflowTrigger)
}

if githubWorkflowSha := ce.GetExtensionGithubWorkflowSha(); githubWorkflowSha != "" {
fmt.Fprintln(os.Stderr, "Certificate extension GitHub Workflow SHA:", githubWorkflowSha)
}
if githubWorkflowName := ce.GetCertExtensionGithubWorkflowName(); githubWorkflowName != "" {
fmt.Fprintln(os.Stderr, "Certificate extension GitHub Workflow Name:", githubWorkflowName)
}

if githubWorkflowRepository := ce.GetCertExtensionGithubWorkflowRepository(); githubWorkflowRepository != "" {
fmt.Fprintln(os.Stderr, "Certificate extension GitHub Workflow Trigger", githubWorkflowRepository)
}

if githubWorkflowRef := ce.GetCertExtensionGithubWorkflowRef(); githubWorkflowRef != "" {
fmt.Fprintln(os.Stderr, "Certificate extension GitHub Workflow Ref:", githubWorkflowRef)
}
}

p, err := sig.Payload()
Expand All @@ -269,13 +299,32 @@ func PrintVerification(imgRef string, verified []oci.Signature, output string) {
}

if cert, err := sig.Cert(); err == nil && cert != nil {
ce := cosign.CertExtensions{Cert: cert}
if ss.Optional == nil {
ss.Optional = make(map[string]interface{})
}
ss.Optional["Subject"] = sigs.CertSubject(cert)
if issuerURL := sigs.CertIssuerExtension(cert); issuerURL != "" {
if issuerURL := ce.GetIssuer(); issuerURL != "" {
ss.Optional["Issuer"] = issuerURL
}
if githubWorkflowTrigger := ce.GetCertExtensionGithubWorkflowTrigger(); githubWorkflowTrigger != "" {
ss.Optional[cosign.CertExtensionGithubWorkflowTrigger] = githubWorkflowTrigger
}

if githubWorkflowSha := ce.GetExtensionGithubWorkflowSha(); githubWorkflowSha != "" {
ss.Optional[cosign.CertExtensionGithubWorkflowSha] = githubWorkflowSha
}
if githubWorkflowName := ce.GetCertExtensionGithubWorkflowName(); githubWorkflowName != "" {
ss.Optional[cosign.CertExtensionGithubWorkflowName] = githubWorkflowName
}

if githubWorkflowRepository := ce.GetCertExtensionGithubWorkflowRepository(); githubWorkflowRepository != "" {
ss.Optional[cosign.CertExtensionGithubWorkflowRepository] = githubWorkflowRepository
}

if githubWorkflowRef := ce.GetCertExtensionGithubWorkflowRef(); githubWorkflowRef != "" {
ss.Optional[cosign.CertExtensionGithubWorkflowRef] = githubWorkflowRef
}
}
if bundle, err := sig.Bundle(); err == nil && bundle != nil {
if ss.Optional == nil {
Expand Down
Loading