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

verify command: support keyless verification using only a provided certificate chain with non-fulcio roots #2845

Merged
merged 5 commits into from
Apr 28, 2023
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
2 changes: 1 addition & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down
4 changes: 4 additions & 0 deletions cmd/cosign/cli/verify.go
Original file line number Diff line number Diff line change
Expand Up @@ -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 <IMAGE>

# 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 <IMAGE>

# verify image with public key provided by URL
cosign verify --key https://host.for/[FILE] <IMAGE>

Expand Down
36 changes: 26 additions & 10 deletions cmd/cosign/cli/verify/verify.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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)
Expand Down
4 changes: 4 additions & 0 deletions doc/cosign_verify.md

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.