Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion xtypes/ecdsa_priv.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ var _ types.Redactor = &ECDSAPrivateKey{}
// UnmarshalParam parses the input as a string.
func (d *ECDSAPrivateKey) UnmarshalParam(in *string) error {
var privK *ecdsa.PrivateKey
if in != nil {
if in != nil && *in != "" {
var err error
privK, err = parseECPrivKey(*in, d.Base64Encoder)
if err != nil {
Expand Down Expand Up @@ -65,6 +65,9 @@ func (d *ECDSAPrivateKey) Value() *ecdsa.PrivateKey {
// ValueValid test if the provided parameter value is valid. Has no side
// effects.
func (d *ECDSAPrivateKey) ValueValid(s string) error {
if s == "" {
return types.ErrNoValue
}
_, err := parseECPrivKey(s, d.Base64Encoder)
return err
}
Expand Down
142 changes: 142 additions & 0 deletions xtypes/ecdsa_priv_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,142 @@
package xtypes_test

import (
"crypto/ecdsa"
"crypto/elliptic"
"crypto/rand"
"crypto/x509"
"encoding/pem"
"reflect"
"testing"

"github.com/simplesurance/proteus"
"github.com/simplesurance/proteus/internal/assert"
"github.com/simplesurance/proteus/sources/cfgtest"
"github.com/simplesurance/proteus/types"
"github.com/simplesurance/proteus/xtypes"
)

func TestECDSAPrivateKey(t *testing.T) {
_, privateKeyStr := generateTestECKey(t)
defaultKey, _ := generateTestECKey(t)

tests := []struct {
name string
params types.ParamValues
shouldErr bool
optionalIsNil bool
useDefault bool
}{
{
name: "valid key for optional and required",
params: types.ParamValues{
"": {
"optionalkey": privateKeyStr,
"requiredkey": privateKeyStr,
},
},
shouldErr: false,
optionalIsNil: false,
},
{
name: "empty string for optional key",
params: types.ParamValues{
"": {
"optionalkey": "",
"requiredkey": privateKeyStr,
},
},
shouldErr: false,
optionalIsNil: true,
},
{
name: "empty string for optional key with default",
params: types.ParamValues{
"": {
"optionalkey": "",
"requiredkey": privateKeyStr,
},
},
shouldErr: false,
optionalIsNil: false,
useDefault: true,
},
{
name: "no value for optional key",
params: types.ParamValues{
"": {
"requiredkey": privateKeyStr,
},
},
shouldErr: false,
optionalIsNil: true,
},
{
name: "empty string for required key",
params: types.ParamValues{
"": {
"requiredkey": "",
},
},
shouldErr: true,
},
{
name: "no value for required key",
params: types.ParamValues{"": {}},
shouldErr: true,
},
}

for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
cfg := struct {
OptionalKey *xtypes.ECDSAPrivateKey `param:",optional"`
RequiredKey *xtypes.ECDSAPrivateKey
}{}

if tt.useDefault {
cfg.OptionalKey = &xtypes.ECDSAPrivateKey{DefaultValue: defaultKey}
}

testProvider := cfgtest.New(tt.params)
defer testProvider.Stop()

_, err := proteus.MustParse(&cfg,
proteus.WithProviders(testProvider))

if tt.shouldErr {
assert.Error(t, err)
} else {
assert.NoError(t, err)
if tt.useDefault {
assert.True(t, reflect.DeepEqual(defaultKey, cfg.OptionalKey.Value()), "default key should be used")
} else if tt.optionalIsNil {
assert.Equal(t, nil, cfg.OptionalKey.Value())
} else {
assert.NotNil(t, cfg.OptionalKey.Value())
}

if _, ok := tt.params[""]["requiredkey"]; ok && tt.params[""]["requiredkey"] != "" {
assert.NotNil(t, cfg.RequiredKey.Value())
}
}
})
}
}

func generateTestECKey(t *testing.T) (*ecdsa.PrivateKey, string) {
t.Helper()
privateKey, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader)
if err != nil {
t.Fatalf("failed to generate ECDSA private key: %v", err)
}
derBytes, err := x509.MarshalECPrivateKey(privateKey)
if err != nil {
t.Fatalf("failed to marshal ECDSA private key: %v", err)
}
pemBlock := &pem.Block{
Type: "EC PRIVATE KEY",
Bytes: derBytes,
}
return privateKey, string(pem.EncodeToMemory(pemBlock))
}
5 changes: 4 additions & 1 deletion xtypes/ecdsa_pub.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ var _ types.XType = &ECDSAPubKey{}
// UnmarshalParam parses the input as a string.
func (d *ECDSAPubKey) UnmarshalParam(in *string) error {
var pubK *ecdsa.PublicKey
if in != nil {
if in != nil && *in != "" {
var err error
pubK, err = parseECPubKey(*in, d.Base64Encoder)
if err != nil {
Expand Down Expand Up @@ -63,6 +63,9 @@ func (d *ECDSAPubKey) Value() *ecdsa.PublicKey {
// ValueValid test if the provided parameter value is valid. Has no side
// effects.
func (d *ECDSAPubKey) ValueValid(s string) error {
if s == "" {
return types.ErrNoValue
}
_, err := parseECPubKey(s, d.Base64Encoder)
return err
}
Expand Down
142 changes: 142 additions & 0 deletions xtypes/ecdsa_pub_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,142 @@
package xtypes_test

import (
"crypto/ecdsa"
"crypto/elliptic"
"crypto/rand"
"crypto/x509"
"encoding/pem"
"reflect"
"testing"

"github.com/simplesurance/proteus"
"github.com/simplesurance/proteus/internal/assert"
"github.com/simplesurance/proteus/sources/cfgtest"
"github.com/simplesurance/proteus/types"
"github.com/simplesurance/proteus/xtypes"
)

func TestECDSAPublicKey(t *testing.T) {
_, publicKeyStr := generateTestECPubKey(t)
defaultKey, _ := generateTestECPubKey(t)

tests := []struct {
name string
params types.ParamValues
shouldErr bool
optionalIsNil bool
useDefault bool
}{
{
name: "valid key for optional and required",
params: types.ParamValues{
"": {
"optionalkey": publicKeyStr,
"requiredkey": publicKeyStr,
},
},
shouldErr: false,
optionalIsNil: false,
},
{
name: "empty string for optional key",
params: types.ParamValues{
"": {
"optionalkey": "",
"requiredkey": publicKeyStr,
},
},
shouldErr: false,
optionalIsNil: true,
},
{
name: "empty string for optional key with default",
params: types.ParamValues{
"": {
"optionalkey": "",
"requiredkey": publicKeyStr,
},
},
shouldErr: false,
optionalIsNil: false,
useDefault: true,
},
{
name: "no value for optional key",
params: types.ParamValues{
"": {
"requiredkey": publicKeyStr,
},
},
shouldErr: false,
optionalIsNil: true,
},
{
name: "empty string for required key",
params: types.ParamValues{
"": {
"requiredkey": "",
},
},
shouldErr: true,
},
{
name: "no value for required key",
params: types.ParamValues{"": {}},
shouldErr: true,
},
}

for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
cfg := struct {
OptionalKey *xtypes.ECDSAPubKey `param:",optional"`
RequiredKey *xtypes.ECDSAPubKey
}{}

if tt.useDefault {
cfg.OptionalKey = &xtypes.ECDSAPubKey{DefaultValue: defaultKey}
}

testProvider := cfgtest.New(tt.params)
defer testProvider.Stop()

_, err := proteus.MustParse(&cfg,
proteus.WithProviders(testProvider))

if tt.shouldErr {
assert.Error(t, err)
} else {
assert.NoError(t, err)
if tt.useDefault {
assert.True(t, reflect.DeepEqual(defaultKey, cfg.OptionalKey.Value()), "default key should be used")
} else if tt.optionalIsNil {
assert.Equal(t, nil, cfg.OptionalKey.Value())
} else {
assert.NotNil(t, cfg.OptionalKey.Value())
}

if _, ok := tt.params[""]["requiredkey"]; ok && tt.params[""]["requiredkey"] != "" {
assert.NotNil(t, cfg.RequiredKey.Value())
}
}
})
}
}

func generateTestECPubKey(t *testing.T) (*ecdsa.PublicKey, string) {
t.Helper()
privateKey, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader)
if err != nil {
t.Fatalf("failed to generate ECDSA private key: %v", err)
}
derBytes, err := x509.MarshalPKIXPublicKey(&privateKey.PublicKey)
if err != nil {
t.Fatalf("failed to marshal ECDSA public key: %v", err)
}
pemBlock := &pem.Block{
Type: "PUBLIC KEY",
Bytes: derBytes,
}
return &privateKey.PublicKey, string(pem.EncodeToMemory(pemBlock))
}
5 changes: 4 additions & 1 deletion xtypes/ed25519_priv.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ var _ types.Redactor = &Ed25519PrivateKey{}
// UnmarshalParam parses the input as a string.
func (d *Ed25519PrivateKey) UnmarshalParam(in *string) error {
var privK ed25519.PrivateKey
if in != nil {
if in != nil && *in != "" {
var err error
privK, err = parseEd25519PrivateKey(*in, d.Base64Encoder)
if err != nil {
Expand Down Expand Up @@ -65,6 +65,9 @@ func (d *Ed25519PrivateKey) Value() ed25519.PrivateKey {
// ValueValid test if the provided parameter value is valid. Has no side
// effects.
func (d *Ed25519PrivateKey) ValueValid(s string) error {
if s == "" {
return types.ErrNoValue
}
_, err := parseEd25519PrivateKey(s, d.Base64Encoder)
return err
}
Expand Down
Loading