From 7d415ff1819c659fd0740854bc3071ba2665cdf8 Mon Sep 17 00:00:00 2001 From: Jan Dittberner Date: Thu, 21 Apr 2022 21:12:34 +0200 Subject: [PATCH] Increase coverage for pkg/config --- pkg/config/config.go | 34 ++++++++++- pkg/config/config_test.go | 123 ++++++++++++++++++++++++++++++++++---- 2 files changed, 143 insertions(+), 14 deletions(-) diff --git a/pkg/config/config.go b/pkg/config/config.go index 25b1fdb..65eff96 100644 --- a/pkg/config/config.go +++ b/pkg/config/config.go @@ -177,6 +177,18 @@ func LoadConfiguration(r io.Reader) (*SignerConfig, error) { return nil, fmt.Errorf("could not parse YAML configuration: %w", err) } + if config.Global == nil { + return nil, errors.New("configuration entry 'Settings' is missing or empty") + } + + if config.CAs == nil { + return nil, errors.New("configuration entry 'CAs' is missing or empty") + } + + if config.KeyStorage == nil { + return nil, errors.New("configuration entry 'KeyStorage' is missing or empty") + } + return &SignerConfig{ global: config.Global, caMap: config.CAs, @@ -192,7 +204,6 @@ type PrivateKeyInfo struct { func (p *PrivateKeyInfo) UnmarshalYAML(value *yaml.Node) error { internalStructure := struct { - Label string `yaml:"label"` Algorithm string `yaml:"algorithm"` EccCurve string `yaml:"ecc-curve,omitempty"` RSABits *int `yaml:"rsa-bits,omitempty"` @@ -207,17 +218,25 @@ func (p *PrivateKeyInfo) UnmarshalYAML(value *yaml.Node) error { case "RSA": p.Algorithm = x509.RSA if internalStructure.RSABits == nil { - return errors.New("RSA key length not specified") + return errors.New("element 'rsa-bits' with RSA key length required for algorithm RSA") } p.RSABits = *internalStructure.RSABits case "EC": p.Algorithm = x509.ECDSA + if internalStructure.EccCurve == "" { + return errors.New("element 'ecc-curve' required for algorithm EC") + } p.EccCurve, err = nameToCurve(internalStructure.EccCurve) if err != nil { return err } + case "": + return errors.New("element 'algorithm' must be specified as 'EC' or 'RSA'") default: - return fmt.Errorf("unsupported key algorithm %s", internalStructure.Algorithm) + return fmt.Errorf( + "unsupported key algorithm %s, use either 'EC' or 'RSA'", + internalStructure.Algorithm, + ) } return nil @@ -302,7 +321,16 @@ func (c *CaCertificateEntry) UnmarshalYAML(value *yaml.Node) error { return err } + if m.KeyInfo == nil { + return errors.New("element 'key-info' must be set") + } + c.KeyInfo = m.KeyInfo + + if m.CommonName == "" { + return errors.New("element 'common-name' must be set") + } + c.CommonName = m.CommonName c.MaxPathLen = m.MaxPathLen diff --git a/pkg/config/config_test.go b/pkg/config/config_test.go index fc09296..7e5b553 100644 --- a/pkg/config/config_test.go +++ b/pkg/config/config_test.go @@ -3,9 +3,11 @@ package config import ( "crypto/elliptic" "crypto/x509" + "strings" "testing" "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" "gopkg.in/yaml.v3" ) @@ -40,11 +42,9 @@ ecc-curve: P-224 for _, item := range testData { t.Run(item.name, func(t *testing.T) { data, err := yaml.Marshal(item.pkInfo) - if err != nil { - t.Fatal(err) - } + require.NoError(t, err) - assert.Equal(t, item.expected, string(data)) + assert.YAMLEq(t, item.expected, string(data)) }) } } @@ -104,10 +104,12 @@ algorithm: "EC"`, t.Run(item.name, func(t *testing.T) { pkInfo := &PrivateKeyInfo{} err := yaml.Unmarshal([]byte(item.yaml), pkInfo) - if err != nil { - if !item.expectErr { - t.Fatal(err) - } + if err != nil && !item.expectErr { + require.NoError(t, err) + } + + if item.expectErr { + assert.Error(t, err) } if !item.expectErr { @@ -130,9 +132,7 @@ func TestCaCertificateEntry_UnmarshalYAML(t *testing.T) { entry := CaCertificateEntry{} err := yaml.Unmarshal([]byte(data), &entry) - if err != nil { - t.Fatal(err) - } + require.NoError(t, err) assert.Equal(t, CaCertificateEntry{ KeyInfo: &PrivateKeyInfo{ @@ -143,3 +143,104 @@ func TestCaCertificateEntry_UnmarshalYAML(t *testing.T) { Storage: "default", }, entry) } + +func TestLoadConfiguration(t *testing.T) { + testData := []struct { + name, yaml string + err bool + }{ + { + name: "Good", + yaml: `--- +Settings: + organization: + validity-years: + root: 20 + intermediary: 5 + url-patterns: +KeyStorage: + default: + type: softhsm +CAs: + root: + common-name: "Root CA" + key-info: + algorithm: EC + ecc-curve: P-384 + sub1: + common-name: "Sub CA 1" + key-info: + algorithm: EC + ecc-curve: P-256 + parent: root + sub2: + common-name: "Sub CA 2" + key-info: + algorithm: EC + ecc-curve: P-256 + parent: root +`, + err: false, + }, + { + name: "Bad", + yaml: `noyamlforyou: ]`, + err: true, + }, + } + + for _, item := range testData { + t.Run(item.name, func(t *testing.T) { + r := strings.NewReader(item.yaml) + sc, err := LoadConfiguration(r) + + if item.err { + assert.Error(t, err) + assert.Nil(t, sc) + } else { + assert.NoError(t, err) + assert.NotNil(t, sc) + } + }) + } +} + +func TestSignerConfig_RootCAs(t *testing.T) { + yamlData := `--- +Settings: + organization: + validity-years: + root: 20 + intermediary: 5 + url-patterns: +KeyStorage: + default: + type: softhsm +CAs: + root: + common-name: "Root CA" + key-info: + algorithm: EC + ecc-curve: P-384 + sub1: + common-name: "Sub CA 1" + key-info: + algorithm: EC + ecc-curve: P-256 + parent: root + sub2: + common-name: "Sub CA 2" + key-info: + algorithm: EC + ecc-curve: P-256 + parent: root +` + r := strings.NewReader(yamlData) + sc, err := LoadConfiguration(r) + + require.NoError(t, err) + require.NotNil(t, sc) + + roots := sc.RootCAs() + assert.Equal(t, roots, []string{"root"}) +}