Skip to content

Commit

Permalink
added implementation for passing in extra options for the kms providers
Browse files Browse the repository at this point in the history
Signed-off-by: chaosinthecrd <[email protected]>
  • Loading branch information
ChaosInTheCRD committed Feb 13, 2024
1 parent a6fa76d commit 1fd8181
Show file tree
Hide file tree
Showing 9 changed files with 137 additions and 32 deletions.
46 changes: 44 additions & 2 deletions cmd/keyloader.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import (
"github.com/in-toto/go-witness/cryptoutil"
"github.com/in-toto/go-witness/log"
"github.com/in-toto/go-witness/signer"
"github.com/in-toto/go-witness/signer/kms"
"github.com/in-toto/witness/options"
"github.com/spf13/pflag"
)
Expand All @@ -46,7 +47,7 @@ func providersFromFlags(prefix string, flags *pflag.FlagSet) map[string]struct{}
}

// loadSigners loads all signers that appear in the signerProviders set and creates their respective signers, using any options provided in so
func loadSigners(ctx context.Context, so options.SignerOptions, signerProviders map[string]struct{}) ([]cryptoutil.Signer, error) {
func loadSigners(ctx context.Context, so options.SignerOptions, ko options.KMSSignerProviderOptions, signerProviders map[string]struct{}) ([]cryptoutil.Signer, error) {
signers := make([]cryptoutil.Signer, 0)
for signerProvider := range signerProviders {
setters := so[signerProvider]
Expand All @@ -56,6 +57,19 @@ func loadSigners(ctx context.Context, so options.SignerOptions, signerProviders
continue
}

// NOTE: We want to initialze the KMS provider specific options if a KMS signer has been invoked
if ksp, ok := sp.(*kms.KMSSignerProvider); ok {
for _, opt := range ksp.Options {
pn := opt.ProviderName()
for _, setter := range ko[pn] {
sp, err = setter(ksp)
if err != nil {
continue
}
}
}
}

s, err := sp.Signer(ctx)
if err != nil {
log.Errorf("failed to create %v signer: %w", signerProvider, err)
Expand All @@ -74,7 +88,7 @@ func loadSigners(ctx context.Context, so options.SignerOptions, signerProviders

// NOTE: This is a temporary implementation until we have a SignerVerifier interface
// loadVerifiers loads all verifiers that appear in the verifierProviders set and creates their respective verifiers, using any options provided in so
func loadVerifiers(ctx context.Context, so options.VerifierOptions, verifierProviders map[string]struct{}) ([]cryptoutil.Verifier, error) {
func loadVerifiers(ctx context.Context, so options.VerifierOptions, ko options.KMSVerifierProviderOptions, verifierProviders map[string]struct{}) ([]cryptoutil.Verifier, error) {
verifiers := make([]cryptoutil.Verifier, 0)
for verifierProvider := range verifierProviders {
setters := so[verifierProvider]
Expand All @@ -84,6 +98,34 @@ func loadVerifiers(ctx context.Context, so options.VerifierOptions, verifierProv
continue
}

// NOTE: We want to initialze the KMS provider specific options if a KMS signer has been invoked
if ksp, ok := sp.(*kms.KMSSignerProvider); ok {
for _, opt := range ksp.Options {
pn := opt.ProviderName()
for _, setter := range ko[pn] {
vp, err := setter(ksp)
if err != nil {
continue
}

// NOTE: KMS SignerProvider can also be a VerifierProvider. This is a nasty hack to cast things back in a way that we can add to the loaded verifiers.
// This must be refactored.
kspv, ok := vp.(*kms.KMSSignerProvider)
if !ok {
return nil, fmt.Errorf("provided verifier provider is not a KMS verifier provider")
}

s, err := kspv.Verifier(ctx)
if err != nil {
log.Errorf("failed to create %v verifier: %w", verifierProvider, err)
continue
}
verifiers = append(verifiers, s)
return verifiers, nil
}
}
}

s, err := sp.Verifier(ctx)
if err != nil {
log.Errorf("failed to create %v verifier: %w", verifierProvider, err)
Expand Down
7 changes: 4 additions & 3 deletions cmd/run.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,8 +36,9 @@ import (

func RunCmd() *cobra.Command {
o := options.RunOptions{
AttestorOptSetters: make(map[string][]func(attestation.Attestor) (attestation.Attestor, error)),
SignerOptions: options.SignerOptions{},
AttestorOptSetters: make(map[string][]func(attestation.Attestor) (attestation.Attestor, error)),
SignerOptions: options.SignerOptions{},
KMSSignerProviderOptions: options.KMSSignerProviderOptions{},
}

cmd := &cobra.Command{
Expand All @@ -46,7 +47,7 @@ func RunCmd() *cobra.Command {
SilenceErrors: true,
SilenceUsage: true,
RunE: func(cmd *cobra.Command, args []string) error {
signers, err := loadSigners(cmd.Context(), o.SignerOptions, providersFromFlags("signer", cmd.Flags()))
signers, err := loadSigners(cmd.Context(), o.SignerOptions, o.KMSSignerProviderOptions, providersFromFlags("signer", cmd.Flags()))
if err != nil {
return fmt.Errorf("failed to load signers: %w", err)
}
Expand Down
5 changes: 3 additions & 2 deletions cmd/sign.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,8 @@ import (

func SignCmd() *cobra.Command {
so := options.SignOptions{
SignerOptions: options.SignerOptions{},
SignerOptions: options.SignerOptions{},
KMSSignerProviderOptions: options.KMSSignerProviderOptions{},
}

cmd := &cobra.Command{
Expand All @@ -40,7 +41,7 @@ func SignCmd() *cobra.Command {
SilenceUsage: true,
DisableAutoGenTag: true,
RunE: func(cmd *cobra.Command, args []string) error {
signers, err := loadSigners(cmd.Context(), so.SignerOptions, providersFromFlags("signer", cmd.Flags()))
signers, err := loadSigners(cmd.Context(), so.SignerOptions, so.KMSSignerProviderOptions, providersFromFlags("signer", cmd.Flags()))
if err != nil {
return fmt.Errorf("failed to load signer: %w", err)
}
Expand Down
8 changes: 6 additions & 2 deletions cmd/verify.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,11 @@ import (
)

func VerifyCmd() *cobra.Command {
vo := options.VerifyOptions{}
vo := options.VerifyOptions{
ArchivistaOptions: options.ArchivistaOptions{},
KMSVerifierProviderOptions: options.KMSVerifierProviderOptions{},
VerifierOptions: options.VerifierOptions{},
}
cmd := &cobra.Command{
Use: "verify",
Short: "Verifies a witness policy",
Expand All @@ -42,7 +46,7 @@ func VerifyCmd() *cobra.Command {
SilenceUsage: true,
DisableAutoGenTag: true,
RunE: func(cmd *cobra.Command, args []string) error {
verifiers, err := loadVerifiers(cmd.Context(), vo.VerifierOptions, providersFromFlags("verifier", cmd.Flags()))
verifiers, err := loadVerifiers(cmd.Context(), vo.VerifierOptions, vo.KMSVerifierProviderOptions, providersFromFlags("verifier", cmd.Flags()))
if err != nil {
return fmt.Errorf("failed to load signer: %w", err)
}
Expand Down
23 changes: 13 additions & 10 deletions options/run.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,16 +21,17 @@ import (
)

type RunOptions struct {
SignerOptions SignerOptions
ArchivistaOptions ArchivistaOptions
WorkingDir string
Attestations []string
Hashes []string
OutFilePath string
StepName string
Tracing bool
TimestampServers []string
AttestorOptSetters map[string][]func(attestation.Attestor) (attestation.Attestor, error)
SignerOptions SignerOptions
KMSSignerProviderOptions KMSSignerProviderOptions
ArchivistaOptions ArchivistaOptions
WorkingDir string
Attestations []string
Hashes []string
OutFilePath string
StepName string
Tracing bool
TimestampServers []string
AttestorOptSetters map[string][]func(attestation.Attestor) (attestation.Attestor, error)
}

func (ro *RunOptions) AddFlags(cmd *cobra.Command) {
Expand All @@ -46,6 +47,8 @@ func (ro *RunOptions) AddFlags(cmd *cobra.Command) {

attestationRegistrations := attestation.RegistrationEntries()
ro.AttestorOptSetters = addFlagsFromRegistry("attestor", attestationRegistrations, cmd)

ro.KMSSignerProviderOptions.AddFlags(cmd)
}

type ArchivistaOptions struct {
Expand Down
12 changes: 7 additions & 5 deletions options/sign.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,15 +17,17 @@ package options
import "github.com/spf13/cobra"

type SignOptions struct {
SignerOptions SignerOptions
DataType string
OutFilePath string
InFilePath string
TimestampServers []string
SignerOptions SignerOptions
KMSSignerProviderOptions KMSSignerProviderOptions
DataType string
OutFilePath string
InFilePath string
TimestampServers []string
}

func (so *SignOptions) AddFlags(cmd *cobra.Command) {
so.SignerOptions.AddFlags(cmd)
so.KMSSignerProviderOptions.AddFlags(cmd)
cmd.Flags().StringVarP(&so.DataType, "datatype", "t", "https://witness.testifysec.com/policy/v0.1", "The URI reference to the type of data being signed. Defaults to the Witness policy type")
cmd.Flags().StringVarP(&so.OutFilePath, "outfile", "o", "", "File to write signed data. Defaults to stdout")
cmd.Flags().StringVarP(&so.InFilePath, "infile", "f", "", "Witness policy file to sign")
Expand Down
25 changes: 25 additions & 0 deletions options/signers.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,12 @@
package options

import (
"fmt"
"strings"

"github.com/in-toto/go-witness/registry"
"github.com/in-toto/go-witness/signer"
"github.com/in-toto/go-witness/signer/kms"
"github.com/spf13/cobra"
)

Expand All @@ -25,3 +30,23 @@ func (so *SignerOptions) AddFlags(cmd *cobra.Command) {
signerRegistrations := signer.RegistryEntries()
*so = addFlagsFromRegistry("signer", signerRegistrations, cmd)
}

type KMSSignerProviderOptions map[string][]func(signer.SignerProvider) (signer.SignerProvider, error)

func (ko *KMSSignerProviderOptions) AddFlags(cmd *cobra.Command) {
kmsProviderOpts := kms.ProviderOptions()
for k, v := range kmsProviderOpts {
if v != nil {
opts := v.Init()
name := fmt.Sprintf("kms-%s", strings.TrimSuffix(k, "kms://"))
// NOTE: this strikes me as a bad idea since it isn't a registry entry. however we wish to piggy back on the add flags logic, and when splitting it out I got errors
entry := []registry.Entry[signer.SignerProvider]{
{
Name: name,
Options: opts,
},
}
*ko = addFlagsFromRegistry[signer.SignerProvider]("signer", entry, cmd)
}
}
}
25 changes: 25 additions & 0 deletions options/verifiers.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,12 @@
package options

import (
"fmt"
"strings"

"github.com/in-toto/go-witness/registry"
"github.com/in-toto/go-witness/signer"
"github.com/in-toto/go-witness/signer/kms"
"github.com/spf13/cobra"
)

Expand All @@ -25,3 +30,23 @@ func (vo *VerifierOptions) AddFlags(cmd *cobra.Command) {
verifierRegistrations := signer.VerifierRegistryEntries()
*vo = addFlagsFromRegistry("verifier", verifierRegistrations, cmd)
}

type KMSVerifierProviderOptions map[string][]func(signer.SignerProvider) (signer.SignerProvider, error)

func (ko *KMSVerifierProviderOptions) AddFlags(cmd *cobra.Command) {
kmsProviderOpts := kms.ProviderOptions()
for k, v := range kmsProviderOpts {
if v != nil {
opts := v.Init()
name := fmt.Sprintf("kms-%s", strings.TrimSuffix(k, "kms://"))
// NOTE: this strikes me as a bad idea since it isn't a registry entry. however we wish to piggy back on the add flags logic, and when splitting it out I got errors
entry := []registry.Entry[signer.SignerProvider]{
{
Name: name,
Options: opts,
},
}
*ko = addFlagsFromRegistry[signer.SignerProvider]("signer", entry, cmd)
}
}
}
18 changes: 10 additions & 8 deletions options/verify.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,19 +17,21 @@ package options
import "github.com/spf13/cobra"

type VerifyOptions struct {
VerifierOptions VerifierOptions
ArchivistaOptions ArchivistaOptions
KeyPath string
AttestationFilePaths []string
PolicyFilePath string
ArtifactFilePath string
AdditionalSubjects []string
CAPaths []string
VerifierOptions VerifierOptions
KMSVerifierProviderOptions KMSVerifierProviderOptions
ArchivistaOptions ArchivistaOptions
KeyPath string
AttestationFilePaths []string
PolicyFilePath string
ArtifactFilePath string
AdditionalSubjects []string
CAPaths []string
}

func (vo *VerifyOptions) AddFlags(cmd *cobra.Command) {
vo.VerifierOptions.AddFlags(cmd)
vo.ArchivistaOptions.AddFlags(cmd)
vo.KMSVerifierProviderOptions.AddFlags(cmd)
cmd.Flags().StringVarP(&vo.KeyPath, "publickey", "k", "", "Path to the policy signer's public key")
cmd.Flags().StringSliceVarP(&vo.AttestationFilePaths, "attestations", "a", []string{}, "Attestation files to test against the policy")
cmd.Flags().StringVarP(&vo.PolicyFilePath, "policy", "p", "", "Path to the policy to verify")
Expand Down

0 comments on commit 1fd8181

Please sign in to comment.