Skip to content

Commit

Permalink
feat: refactor 3
Browse files Browse the repository at this point in the history
Signed-off-by: Juncheng Zhu <[email protected]>
  • Loading branch information
junczhu committed Feb 17, 2025
1 parent 8671266 commit db55766
Show file tree
Hide file tree
Showing 2 changed files with 56 additions and 59 deletions.
9 changes: 6 additions & 3 deletions cosign/truststore.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,32 +13,35 @@ 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),
}
}

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) {
Expand Down
106 changes: 50 additions & 56 deletions cosign/verifier.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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)
}
Expand All @@ -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
Expand Down Expand Up @@ -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)
}
Expand All @@ -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
Expand Down Expand Up @@ -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 {
Expand All @@ -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{
Expand Down

0 comments on commit db55766

Please sign in to comment.