Skip to content

Commit

Permalink
expand loadCerts helper, takes isKeyless as bool param
Browse files Browse the repository at this point in the history
Signed-off-by: Dmitry S <[email protected]>
  • Loading branch information
dmitris committed Jul 3, 2024
1 parent 855bfb4 commit 37418e3
Show file tree
Hide file tree
Showing 8 changed files with 67 additions and 29 deletions.
20 changes: 15 additions & 5 deletions cmd/cosign/cli/verify.go
Original file line number Diff line number Diff line change
Expand Up @@ -114,14 +114,14 @@ against the transparency log.`,
CheckClaims: o.CheckClaims,
KeyRef: o.Key,
CertRef: o.CertVerify.Cert,
CertChain: o.CertVerify.CertChain,
CAIntermediates: o.CertVerify.CAIntermediates,
CARoots: o.CertVerify.CARoots,
CertGithubWorkflowTrigger: o.CertVerify.CertGithubWorkflowTrigger,
CertGithubWorkflowSha: o.CertVerify.CertGithubWorkflowSha,
CertGithubWorkflowName: o.CertVerify.CertGithubWorkflowName,
CertGithubWorkflowRepository: o.CertVerify.CertGithubWorkflowRepository,
CertGithubWorkflowRef: o.CertVerify.CertGithubWorkflowRef,
CAIntermediates: o.CertVerify.CAIntermediates,
CARoots: o.CertVerify.CARoots,
CertChain: o.CertVerify.CertChain,
IgnoreSCT: o.CertVerify.IgnoreSCT,
SCTRef: o.CertVerify.SCT,
Sk: o.SecurityKey.Use,
Expand Down Expand Up @@ -223,13 +223,13 @@ against the transparency log.`,
CertVerifyOptions: o.CertVerify,
CertRef: o.CertVerify.Cert,
CertChain: o.CertVerify.CertChain,
CAIntermediates: o.CertVerify.CAIntermediates,
CARoots: o.CertVerify.CARoots,
CertGithubWorkflowTrigger: o.CertVerify.CertGithubWorkflowTrigger,
CertGithubWorkflowSha: o.CertVerify.CertGithubWorkflowSha,
CertGithubWorkflowName: o.CertVerify.CertGithubWorkflowName,
CertGithubWorkflowRepository: o.CertVerify.CertGithubWorkflowRepository,
CertGithubWorkflowRef: o.CertVerify.CertGithubWorkflowRef,
CAIntermediates: o.CertVerify.CAIntermediates,
CARoots: o.CertVerify.CARoots,
IgnoreSCT: o.CertVerify.IgnoreSCT,
SCTRef: o.CertVerify.SCT,
KeyRef: o.Key,
Expand Down Expand Up @@ -283,6 +283,12 @@ The blob may be specified as a path to a file or - for stdin.`,
# Verify a simple blob and message
cosign verify-blob --key cosign.pub (--signature <sig path>|<sig url> msg)
# Verify a signature with certificate and CA certificate chain
cosign verify-blob --certificate cert.pem --certificate-chain certchain.pem --signature $sig <blob>
# Verify a signature with CA roots and optional intermediate certificates
cosign verify-blob --certificate cert.pem --ca-roots caroots.pem [--ca-intermediates caintermediates.pem] --signature $sig <blob>
# Verify a signature from an environment variable
cosign verify-blob --key cosign.pub --signature $sig msg
Expand Down Expand Up @@ -335,6 +341,8 @@ The blob may be specified as a path to a file or - for stdin.`,
CertVerifyOptions: o.CertVerify,
CertRef: o.CertVerify.Cert,
CertChain: o.CertVerify.CertChain,
CARoots: o.CertVerify.CARoots,
CAIntermediates: o.CertVerify.CAIntermediates,
SigRef: o.Signature,
CertGithubWorkflowTrigger: o.CertVerify.CertGithubWorkflowTrigger,
CertGithubWorkflowSHA: o.CertVerify.CertGithubWorkflowSha,
Expand Down Expand Up @@ -404,6 +412,8 @@ The blob may be specified as a path to a file.`,
CertVerifyOptions: o.CertVerify,
CertRef: o.CertVerify.Cert,
CertChain: o.CertVerify.CertChain,
CARoots: o.CertVerify.CARoots,
CAIntermediates: o.CertVerify.CAIntermediates,
CertGithubWorkflowTrigger: o.CertVerify.CertGithubWorkflowTrigger,
CertGithubWorkflowSHA: o.CertVerify.CertGithubWorkflowSha,
CertGithubWorkflowName: o.CertVerify.CertGithubWorkflowName,
Expand Down
23 changes: 14 additions & 9 deletions cmd/cosign/cli/verify/verify.go
Original file line number Diff line number Diff line change
Expand Up @@ -174,11 +174,10 @@ func (c *VerifyCommand) Exec(ctx context.Context, images []string) (err error) {
return fmt.Errorf("getting Rekor public keys: %w", err)
}
}
if keylessVerification(c.KeyRef, c.Sk) {
if err := loadCertsKeylessVerification(c.CertChain, c.CARoots, c.CAIntermediates, co); err != nil {
return err
}
if err := loadCerts(keylessVerification(c.KeyRef, c.Sk), c.CertChain, c.CARoots, c.CAIntermediates, co); err != nil {
return err
}

keyRef := c.KeyRef
certRef := c.CertRef

Expand Down Expand Up @@ -511,16 +510,17 @@ func shouldVerifySCT(ignoreSCT bool, keyRef string, sk bool) bool {
return true
}

// loadCertsKeylessVerification loads certificates for the verification of keyless signatures
// for the verify command.
// loadCerts loads certificates provided as a certificate chain or CA roots + CA intermediate
// certificate files. If both certChain and caRootsFile are empty strings, the Fulcio roots are loaded,
// but only in the case of keyless verification.
//
// TODO(dmitris) - mention additionally verify-attestation, verify-blob, verify-blob-attestation
// commands when they are extended to call this function.
//
// The co *cosign.CheckOpts is both input and output parameter - it gets updated
// with the root and intermediate certificates needed for verification.
// If both certChain and caRootsFile are empty strings, the Fulcio roots are loaded.
func loadCertsKeylessVerification(certChainFile string,
func loadCerts(keylessVerification bool,
certChainFile string,
caRootsFile string,
caIntermediatesFile string,
co *cosign.CheckOpts) error {
Expand All @@ -539,6 +539,7 @@ func loadCertsKeylessVerification(certChainFile string,
co.IntermediateCerts.AddCert(cert)
}
}

case caRootsFile != "":
caRoots, err := loadCertChainFromFileOrURL(caRootsFile)
if err != nil {
Expand All @@ -562,7 +563,8 @@ func loadCertsKeylessVerification(certChainFile string,
}
}
}
default:

case keylessVerification:
// This performs an online fetch of the Fulcio roots from a TUF repository.
// This is needed for verifying keyless certificates (both online and offline).
co.RootCerts, err = fulcio.GetRoots()
Expand All @@ -573,6 +575,9 @@ func loadCertsKeylessVerification(certChainFile string,
if err != nil {
return fmt.Errorf("getting Fulcio intermediates: %w", err)
}

default: // do nothing if keylessVerification is false and no certChain or caRootsFile is provided
}

return nil
}
6 changes: 2 additions & 4 deletions cmd/cosign/cli/verify/verify_attestation.go
Original file line number Diff line number Diff line change
Expand Up @@ -157,10 +157,8 @@ func (c *VerifyAttestationCommand) Exec(ctx context.Context, images []string) (e
}
}

if keylessVerification(c.KeyRef, c.Sk) {
if err := loadCertsKeylessVerification(c.CertChain, c.CARoots, c.CAIntermediates, co); err != nil {
return err
}
if err := loadCerts(keylessVerification(c.KeyRef, c.Sk), c.CertChain, c.CARoots, c.CAIntermediates, co); err != nil {
return err
}

keyRef := c.KeyRef
Expand Down
16 changes: 11 additions & 5 deletions cmd/cosign/cli/verify/verify_blob.go
Original file line number Diff line number Diff line change
Expand Up @@ -152,10 +152,13 @@ func (c *VerifyBlobCmd) Exec(ctx context.Context, blobRef string) error {
return fmt.Errorf("getting Rekor public keys: %w", err)
}
}
if keylessVerification(c.KeyRef, c.Sk) {
if err := loadCertsKeylessVerification(c.CertChain, c.CARoots, c.CAIntermediates, co); err != nil {
return err
}

if err := loadCerts(keylessVerification(c.KeyRef, c.Sk),
c.CertChain,
c.CARoots,
c.CAIntermediates,
co); err != nil {
return err
}

// Keys are optional!
Expand Down Expand Up @@ -240,7 +243,8 @@ func (c *VerifyBlobCmd) Exec(ctx context.Context, blobRef string) error {
}
// Set a cert chain if provided.
var chainPEM []byte
if c.CertChain != "" {
switch {
case c.CertChain != "":
chain, err := loadCertChainFromFileOrURL(c.CertChain)
if err != nil {
return err
Expand All @@ -260,6 +264,8 @@ func (c *VerifyBlobCmd) Exec(ctx context.Context, blobRef string) error {
if err != nil {
return err
}
case c.CARoots != "":
// TODO(dmitris) insert CA roots + intermediates into the signature options for verification
}

// Gather the cert for the signature and add the cert along with the
Expand Down
6 changes: 2 additions & 4 deletions cmd/cosign/cli/verify/verify_blob_attestation.go
Original file line number Diff line number Diff line change
Expand Up @@ -170,10 +170,8 @@ func (c *VerifyBlobAttestationCommand) Exec(ctx context.Context, artifactPath st
return fmt.Errorf("getting Rekor public keys: %w", err)
}
}
if keylessVerification(c.KeyRef, c.Sk) {
if err := loadCertsKeylessVerification(c.CertChain, c.CARoots, c.CAIntermediates, co); err != nil {
return err
}
if err := loadCerts(keylessVerification(c.KeyRef, c.Sk), c.CertChain, c.CARoots, c.CAIntermediates, co); err != nil {
return err
}

// Ignore Signed Certificate Timestamp if the flag is set or a key is provided
Expand Down
9 changes: 7 additions & 2 deletions cmd/cosign/cli/verify/verify_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -264,7 +264,7 @@ func TestVerifyCertMissingIssuer(t *testing.T) {
}
}

func TestLoadCertsKeylessVerification(t *testing.T) {
func TestLoadCerts(t *testing.T) {
certs := getTestCerts(t)
certChainFile := makeCertChainFile(t, certs.RootCertPEM, certs.SubCertPEM, certs.LeafCertPEM)
rootsFile, intermediatesFile := makeRootsIntermediatesFiles(t, certs.RootCertPEM, certs.SubCertPEM)
Expand All @@ -275,12 +275,17 @@ func TestLoadCertsKeylessVerification(t *testing.T) {
caIntermediates string
co *cosign.CheckOpts
sigstoreRootFile string
nonKeyless bool
wantErr bool
}{
{
name: "default fulcio",
wantErr: false,
},
{
name: "non-keyless no-op",
wantErr: false,
},
{
name: "non-existent SIGSTORE_ROOT_FILE",
sigstoreRootFile: "tesdata/nosuch-asdfjkl.pem",
Expand Down Expand Up @@ -337,7 +342,7 @@ func TestLoadCertsKeylessVerification(t *testing.T) {
tt.co = &cosign.CheckOpts{}
}

err := loadCertsKeylessVerification(tt.certChain, tt.caRoots, tt.caIntermediates, tt.co)
err := loadCerts(!tt.nonKeyless, tt.certChain, tt.caRoots, tt.caIntermediates, tt.co)
if err == nil && tt.wantErr {
t.Fatalf("expected error but got none")
} else if err != nil && !tt.wantErr {
Expand Down
6 changes: 6 additions & 0 deletions doc/cosign_verify-blob.md

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

10 changes: 10 additions & 0 deletions pkg/oci/static/options.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,8 @@ type options struct {
RFC3161Timestamp *bundle.RFC3161Timestamp
Cert []byte
Chain []byte
RootCerts []byte
IntermediateCerts [][]byte
Annotations map[string]string
RecordCreationTimestamp bool
}
Expand Down Expand Up @@ -114,6 +116,14 @@ func WithCertChain(cert, chain []byte) Option {
}
}

// Wr sets the CA root and intermediates certificates for this signature.
func WithRootsIntermediates(roots []byte, intermediates [][]byte) Option {
return func(o *options) {
o.RootCerts = roots
o.IntermediateCerts = intermediates
}
}

// WithRecordCreationTimestamp sets the feature flag to honor the creation timestamp to time of running
func WithRecordCreationTimestamp(rct bool) Option {
return func(o *options) {
Expand Down

0 comments on commit 37418e3

Please sign in to comment.