diff --git a/CHANGELOG.md b/CHANGELOG.md index f14de5f5238..d13e9f3b03e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -358,7 +358,7 @@ Critical breaking changes include: # v1.12.1 > # Highlights -> * Pulls Fulcio root and intermediate when `--certificate-chain` is not passed into `verify-blob`. The v1.12.0 release introduced a regression: when `COSIGN_EXPERIMENTAL` was not set, cosign `verify-blob` would check a` --certificate` (without a `--certificate-chain` provided) against the operating system root CA bundle. In this release, Cosign checks the certificate against Fulcio's CA root instead (restoring the earlier behavior). +> * Pulls Fulcio root and intermediate when `--certificate-chain` is not passed into `verify-blob`. The v1.12.0 release introduced a regression: when `COSIGN_EXPERIMENTAL` was not set, cosign `verify-blob` would check a `--certificate` (without a `--certificate-chain` provided) against the operating system root CA bundle. In this release, Cosign checks the certificate against Fulcio's CA root instead (restoring the earlier behavior). ## Bug Fixes diff --git a/cmd/cosign/cli/verify.go b/cmd/cosign/cli/verify.go index df9820df6a8..e48a856eeef 100644 --- a/cmd/cosign/cli/verify.go +++ b/cmd/cosign/cli/verify.go @@ -61,6 +61,10 @@ against the transparency log.`, # verify image with local certificate and certificate chain cosign verify --cert cosign.crt --cert-chain chain.crt + # verify image using keyless verification with the given certificate + # chain and identity parameters, without Fulcio roots (for BYO PKI): + cosign verify --cert-chain chain.crt --certificate-oidc-issuer https://issuer.example.com --certificate-identity foo@example.com + # verify image with public key provided by URL cosign verify --key https://host.for/[FILE] diff --git a/cmd/cosign/cli/verify/verify.go b/cmd/cosign/cli/verify/verify.go index 0a1348fc290..38fc77475f4 100644 --- a/cmd/cosign/cli/verify/verify.go +++ b/cmd/cosign/cli/verify/verify.go @@ -171,15 +171,30 @@ func (c *VerifyCommand) Exec(ctx context.Context, images []string) (err error) { } } if keylessVerification(c.KeyRef, c.Sk) { - // This performs an online fetch of the Fulcio roots. This is needed - // for verifying keyless certificates (both online and offline). - 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) + if c.CertChain != "" { + chain, err := loadCertChainFromFileOrURL(c.CertChain) + if err != nil { + return err + } + co.RootCerts = x509.NewCertPool() + co.RootCerts.AddCert(chain[len(chain)-1]) + if len(chain) > 1 { + co.IntermediateCerts = x509.NewCertPool() + for _, cert := range chain[:len(chain)-1] { + co.IntermediateCerts.AddCert(cert) + } + } + } else { + // This performs an online fetch of the Fulcio roots. This is needed + // for verifying keyless certificates (both online and offline). + 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 @@ -256,7 +271,8 @@ func (c *VerifyCommand) Exec(ctx context.Context, images []string) (err error) { // 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 + // 2. We’re going to find an x509 certificate on the signature and verify against + // Fulcio root trust (or user supplied 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) diff --git a/doc/cosign_verify.md b/doc/cosign_verify.md index 48294bf55a3..72c924d9eb2 100644 --- a/doc/cosign_verify.md +++ b/doc/cosign_verify.md @@ -38,6 +38,10 @@ cosign verify [flags] # verify image with local certificate and certificate chain cosign verify --cert cosign.crt --cert-chain chain.crt + # verify image using keyless verification with the given certificate + # chain and identity parameters, without Fulcio roots (for BYO PKI): + cosign verify --cert-chain chain.crt --certificate-oidc-issuer https://issuer.example.com --certificate-identity foo@example.com + # verify image with public key provided by URL cosign verify --key https://host.for/[FILE]