From db5576612ee63c5791be8b7cf7f00b33f65775c4 Mon Sep 17 00:00:00 2001 From: Juncheng Zhu Date: Mon, 17 Feb 2025 04:34:54 +0000 Subject: [PATCH] feat: refactor 3 Signed-off-by: Juncheng Zhu --- cosign/truststore.go | 9 ++-- cosign/verifier.go | 106 ++++++++++++++++++++----------------------- 2 files changed, 56 insertions(+), 59 deletions(-) diff --git a/cosign/truststore.go b/cosign/truststore.go index 6d16f51..352ba5b 100644 --- a/cosign/truststore.go +++ b/cosign/truststore.go @@ -13,24 +13,27 @@ type TrustStore interface { } type VOptions struct { - HashAlgorithm int + HashAlgorithm crypto.Hash KeyRef string Sk bool Slot string CertRef string CertChain string SCTRef string + IgnoreSCT bool } type TrustStoreImp struct { - OptsMap map[string]*VOptions + optsMap map[string]*VOptions keysMap map[string]crypto.PublicKey certMap map[string]*x509.Certificate certChains map[string][]*x509.Certificate } func NewWithOpts(opts *VerifierOptions) TrustStore { + // TODO: get maps from opts.VerifyCommand return &TrustStoreImp{ + optsMap: make(map[string]*VOptions), keysMap: make(map[string]crypto.PublicKey), certMap: make(map[string]*x509.Certificate), certChains: make(map[string][]*x509.Certificate), @@ -38,7 +41,7 @@ func NewWithOpts(opts *VerifierOptions) TrustStore { } func (t *TrustStoreImp) GetVerifyOpts(subjectRef string) (*VOptions, error) { - return t.OptsMap[subjectRef], nil + return t.optsMap[subjectRef], nil } func (t *TrustStoreImp) GetKey(keyRef string) (crypto.PublicKey, error) { diff --git a/cosign/verifier.go b/cosign/verifier.go index b2718c3..8e375a1 100644 --- a/cosign/verifier.go +++ b/cosign/verifier.go @@ -51,7 +51,8 @@ type VerifierOptions struct { Name string // VerifyCommand is a stuct contains params that executes the verification process. - verify.VerifyCommand + // TODO: Update this field to a struct hold multi-VerfiyCommands + *verify.VerifyCommand } // Verifier is a ratify.Verifier implementation that verifies cosign @@ -63,11 +64,8 @@ type Verifier struct { } // NewVerifier creates a new cosign verifier. -// -// Parameters: -// - opts: Options for creating the verifier, including the name and check options. func NewVerifier(opts *VerifierOptions) (*Verifier, error) { - checkOpts, err := NewCheckOpts(context.Background(), &opts.VerifyCommand) + checkOpts, err := NewCheckOpts(context.Background(), opts.VerifyCommand) if err != nil { return nil, fmt.Errorf("failed to update signature verifier keys: %w", err) } @@ -82,6 +80,47 @@ func NewVerifier(opts *VerifierOptions) (*Verifier, error) { }, nil } +// NewCheckOpts updates the signature verifierOpts by verifierOptions. +func NewCheckOpts(ctx context.Context, c *verify.VerifyCommand) (opts *cosign.CheckOpts, err error) { + // initialize the cosign check options + opts = &cosign.CheckOpts{} + + if c.CheckClaims { + opts.ClaimVerifier = cosign.SimpleClaimVerifier + } + + // If we are using signed timestamps, we need to load the TSA certificates + if c.TSACertChainPath != "" || c.UseSignedTimestamps { + tsaCertificates, err := cosign.GetTSACerts(ctx, c.TSACertChainPath, cosign.GetTufTargets) + if err != nil { + return nil, fmt.Errorf("unable to load TSA certificates: %w", err) + } + opts.TSACertificate = tsaCertificates.LeafCert + opts.TSARootCertificates = tsaCertificates.RootCert + opts.TSAIntermediateCertificates = tsaCertificates.IntermediateCerts + } + + if !c.IgnoreTlog { + if c.RekorURL == "" { + c.RekorURL = defaultRekorURL + } + + rekorClient, err := rekor.NewClient(c.RekorURL) + if err != nil { + return nil, fmt.Errorf("creating Rekor client: %w", err) + } + opts.RekorClient = rekorClient + + // This performs an online fetch of the Rekor public keys, but this is needed + // for verifying tlog entries (both online and offline). + opts.RekorPubKeys, err = cosign.GetRekorPubs(ctx) + if err != nil { + return nil, fmt.Errorf("getting Rekor public keys: %w", err) + } + } + return opts, nil +} + // Name returns the name of the verifier. func (v *Verifier) Name() string { return v.name @@ -153,7 +192,8 @@ func (v *Verifier) Verify(ctx context.Context, opts *ratify.VerifyOptions) (*rat // MapSigVerifier maps and returns a signature verifier based on the provided VerifyCommand and CheckOpts. // It supports different types of verifiers including key references, security keys, and certificate references. func (v *Verifier) MapSigVerifier(ctx context.Context, opts *ratify.VerifyOptions) (err error) { - c, err := getVerifyCommandFromOpts(v, opts) + // TODO: update default values for the verifier options + c, err := v.truststore.GetVerifyOpts(opts.Subject) if err != nil { return fmt.Errorf("failed to get verify command from options: %w", err) } @@ -165,16 +205,16 @@ func (v *Verifier) MapSigVerifier(ctx context.Context, opts *ratify.VerifyOption } } - var pubKey signature.Verifier + var pubKey signature.Verifier = nil switch { case c.KeyRef != "": - if c.HashAlgorithm == 0 { - c.HashAlgorithm = crypto.SHA256 - } key, err := v.truststore.GetKey(c.KeyRef) if err != nil { return fmt.Errorf("getting key: %w", err) } + if c.HashAlgorithm == 0 { + c.HashAlgorithm = crypto.SHA256 + } pubKey, err = signature.LoadVerifier(key, c.HashAlgorithm) if err != nil { return err @@ -249,47 +289,6 @@ func (v *Verifier) MapSigVerifier(ctx context.Context, opts *ratify.VerifyOption return nil } -// NewCheckOpts updates the signature verifierOpts by verifierOptions. -func NewCheckOpts(ctx context.Context, c *verify.VerifyCommand) (opts *cosign.CheckOpts, err error) { - // initialize the cosign check options - opts = &cosign.CheckOpts{} - - if c.CheckClaims { - opts.ClaimVerifier = cosign.SimpleClaimVerifier - } - - // If we are using signed timestamps, we need to load the TSA certificates - if c.TSACertChainPath != "" || c.UseSignedTimestamps { - tsaCertificates, err := cosign.GetTSACerts(ctx, c.TSACertChainPath, cosign.GetTufTargets) - if err != nil { - return nil, fmt.Errorf("unable to load TSA certificates: %w", err) - } - opts.TSACertificate = tsaCertificates.LeafCert - opts.TSARootCertificates = tsaCertificates.RootCert - opts.TSAIntermediateCertificates = tsaCertificates.IntermediateCerts - } - - if !c.IgnoreTlog { - if c.RekorURL == "" { - c.RekorURL = defaultRekorURL - } - - rekorClient, err := rekor.NewClient(c.RekorURL) - if err != nil { - return nil, fmt.Errorf("creating Rekor client: %w", err) - } - opts.RekorClient = rekorClient - - // This performs an online fetch of the Rekor public keys, but this is needed - // for verifying tlog entries (both online and offline). - opts.RekorPubKeys, err = cosign.GetRekorPubs(ctx) - if err != nil { - return nil, fmt.Errorf("getting Rekor public keys: %w", err) - } - } - return opts, nil -} - func getSignatureBlobDesc(ctx context.Context, store ratify.Store, artifactRef registry.Reference, artifactDesc ocispec.Descriptor) ([]ocispec.Descriptor, error) { manifest, err := store.FetchImageManifest(ctx, artifactRef.Registry+"/"+artifactRef.Repository, artifactDesc) if err != nil { @@ -305,11 +304,6 @@ func getSignatureBlobDesc(ctx context.Context, store ratify.Store, artifactRef r return signatureLayers, nil } -func getVerifyCommandFromOpts(v *Verifier, opts *ratify.VerifyOptions) (*verify.VerifyCommand, error) { - v.truststore.GetVerifyOpts(opts.Subject) - return nil, nil -} - // staticLayerOpts builds the cosign options for static layer signatures. func staticLayerOpts(desc ocispec.Descriptor) ([]static.Option, error) { options := []static.Option{