Skip to content
This repository has been archived by the owner on Aug 25, 2023. It is now read-only.

Commit

Permalink
Merge pull request #342 from rajeshkalaria80/add-key-alias-support
Browse files Browse the repository at this point in the history
feat: changes to add key alias support
  • Loading branch information
fqutishat authored Dec 5, 2022
2 parents f895f91 + 6ec004f commit 50a50d5
Show file tree
Hide file tree
Showing 7 changed files with 151 additions and 28 deletions.
4 changes: 2 additions & 2 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,15 @@ go 1.18

require (
github.com/aws/aws-sdk-go v1.42.33
github.com/btcsuite/btcd v0.22.1
github.com/golang/mock v1.6.0
github.com/google/tink/go v1.6.1
github.com/gorilla/mux v1.8.0
github.com/hyperledger/aries-framework-go v0.1.9-0.20220822173318-77fbef728d02
github.com/hyperledger/aries-framework-go/component/storageutil v0.0.0-20220610133818-119077b0ec85
github.com/hyperledger/aries-framework-go/spi v0.0.0-20220610133818-119077b0ec85
github.com/igor-pavlenko/httpsignatures-go v0.0.23
github.com/minio/sha256-simd v0.1.1
github.com/piprate/json-gold v0.4.1
github.com/prometheus/client_golang v1.11.0
github.com/rs/xid v1.3.0
Expand All @@ -29,7 +31,6 @@ require (
github.com/VictoriaMetrics/fastcache v1.5.7 // indirect
github.com/beorn7/perks v1.0.1 // indirect
github.com/bluele/gcache v0.0.2 // indirect
github.com/btcsuite/btcd v0.22.1 // indirect
github.com/btcsuite/btcutil v1.0.3-0.20201208143702-a53e38424cce // indirect
github.com/cenkalti/backoff/v4 v4.1.2 // indirect
github.com/cespare/xxhash/v2 v2.1.2 // indirect
Expand All @@ -45,7 +46,6 @@ require (
github.com/kilic/bls12-381 v0.1.1-0.20210503002446-7b7597926c69 // indirect
github.com/matttproud/golang_protobuf_extensions v1.0.1 // indirect
github.com/minio/blake2b-simd v0.0.0-20160723061019-3f5f724cb5b1 // indirect
github.com/minio/sha256-simd v0.1.1 // indirect
github.com/mitchellh/mapstructure v1.4.3 // indirect
github.com/mr-tron/base58 v1.2.0 // indirect
github.com/multiformats/go-base32 v0.0.4 // indirect
Expand Down
36 changes: 36 additions & 0 deletions pkg/aws/opts.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
/*
Copyright SecureKey Technologies Inc. All Rights Reserved.
SPDX-License-Identifier: Apache-2.0
*/

package aws

import (
"os"
)

type opts struct {
keyAliasPrefix string
}

// NewOpts create new opts populated with environment variable.
func newOpts() *opts {
value, _ := os.LookupEnv("AWS_KEY_ALIAS_PREFIX")

return &opts{
keyAliasPrefix: value,
}
}

func (o *opts) KeyAliasPrefix() string {
return o.keyAliasPrefix
}

// Opts a Functional Options.
type Opts func(opts *opts)

// WithKeyAliasPrefix sets the given prefix in the returns Opts.
func WithKeyAliasPrefix(prefix string) Opts {
return func(opts *opts) { opts.keyAliasPrefix = prefix }
}
37 changes: 37 additions & 0 deletions pkg/aws/opts_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
/*
Copyright SecureKey Technologies Inc. All Rights Reserved.
SPDX-License-Identifier: Apache-2.0
*/

package aws //nolint:testpackage

import (
"testing"

"github.com/stretchr/testify/require"
)

func TestOpts(t *testing.T) {
t.Run("options: defaults", func(t *testing.T) {
options := newOpts()

require.Equal(t, "", options.KeyAliasPrefix())
})

t.Run("options: set manually", func(t *testing.T) {
options := newOpts()

WithKeyAliasPrefix("keyaliasprefix")(options)

require.Equal(t, "keyaliasprefix", options.KeyAliasPrefix())
})

t.Run("options: env vars", func(t *testing.T) {
t.Setenv("AWS_KEY_ALIAS_PREFIX", "keyaliasprefix")

options := newOpts()

require.Equal(t, "keyaliasprefix", options.KeyAliasPrefix())
})
}
24 changes: 21 additions & 3 deletions pkg/aws/service.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,12 +25,13 @@ import (
"github.com/minio/sha256-simd"
)

type awsClient interface {
type awsClient interface { //nolint:dupl
Sign(input *kms.SignInput) (*kms.SignOutput, error)
GetPublicKey(input *kms.GetPublicKeyInput) (*kms.GetPublicKeyOutput, error)
Verify(input *kms.VerifyInput) (*kms.VerifyOutput, error)
DescribeKey(input *kms.DescribeKeyInput) (*kms.DescribeKeyOutput, error)
CreateKey(input *kms.CreateKeyInput) (*kms.CreateKeyOutput, error)
CreateAlias(input *kms.CreateAliasInput) (*kms.CreateAliasOutput, error)
}

type metricsProvider interface {
Expand All @@ -48,6 +49,7 @@ type ecdsaSignature struct {

// Service aws kms.
type Service struct {
options *opts
client awsClient
metrics metricsProvider
healthCheckKeyID string
Expand All @@ -73,8 +75,14 @@ var keySpecToCurve = map[string]elliptic.Curve{
}

// New return aws service.
func New(awsSession *session.Session, metrics metricsProvider, healthCheckKeyID string) *Service {
return &Service{client: kms.New(awsSession), metrics: metrics, healthCheckKeyID: healthCheckKeyID}
func New(awsSession *session.Session, metrics metricsProvider, healthCheckKeyID string, opts ...Opts) *Service {
options := newOpts()

for _, opt := range opts {
opt(options)
}

return &Service{options: options, client: kms.New(awsSession), metrics: metrics, healthCheckKeyID: healthCheckKeyID}
}

// Sign data.
Expand Down Expand Up @@ -226,6 +234,16 @@ func (s *Service) Create(kt arieskms.KeyType) (string, interface{}, error) {
return "", nil, err
}

aliasPrefix := s.options.KeyAliasPrefix()
if strings.TrimSpace(aliasPrefix) != "" {
aliasName := fmt.Sprintf("%s.%s", aliasPrefix, *result.KeyMetadata.KeyId)

_, err = s.client.CreateAlias(&kms.CreateAliasInput{AliasName: &aliasName, TargetKeyId: result.KeyMetadata.KeyId})
if err != nil {
return "", nil, err
}
}

return *result.KeyMetadata.KeyId, *result.KeyMetadata.KeyId, nil
}

Expand Down
65 changes: 52 additions & 13 deletions pkg/aws/service_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,9 +30,10 @@ func TestSign(t *testing.T) {
Region: aws.String("ca"),
CredentialsChainVerboseErrors: aws.Bool(true),
})

require.NoError(t, err)

svc := New(awsSession, &mockMetrics{}, "")
svc := New(awsSession, &mockMetrics{}, "", []Opts{}...)

svc.client = &mockAWSClient{signFunc: func(input *kms.SignInput) (*kms.SignOutput, error) {
return &kms.SignOutput{
Expand Down Expand Up @@ -62,7 +63,7 @@ func TestSign(t *testing.T) {
})
require.NoError(t, err)

svc := New(awsSession, &mockMetrics{}, "")
svc := New(awsSession, &mockMetrics{}, "", []Opts{}...)

svc.client = &mockAWSClient{signFunc: func(input *kms.SignInput) (*kms.SignOutput, error) {
return nil, fmt.Errorf("failed to sign")
Expand All @@ -89,7 +90,7 @@ func TestSign(t *testing.T) {
})
require.NoError(t, err)

svc := New(awsSession, &mockMetrics{}, "")
svc := New(awsSession, &mockMetrics{}, "", []Opts{}...)

_, err = svc.Sign([]byte("msg"), "aws-kms://arn:aws:kms:key1")
require.Error(t, err)
Expand All @@ -108,7 +109,8 @@ func TestHealthCheck(t *testing.T) {
require.NoError(t, err)

svc := New(awsSession, &mockMetrics{},
"aws-kms://arn:aws:kms:ca-central-1:111122223333:key/800d5768-3fd7-4edd-a4b8-4c81c3e4c147")
"aws-kms://arn:aws:kms:ca-central-1:111122223333:key/800d5768-3fd7-4edd-a4b8-4c81c3e4c147",
[]Opts{}...)

svc.client = &mockAWSClient{describeKeyFunc: func(input *kms.DescribeKeyInput) (*kms.DescribeKeyOutput, error) {
return &kms.DescribeKeyOutput{}, nil
Expand All @@ -128,7 +130,8 @@ func TestHealthCheck(t *testing.T) {
require.NoError(t, err)

svc := New(awsSession, &mockMetrics{},
"aws-kms://arn:aws:kms:ca-central-1:111122223333:key/800d5768-3fd7-4edd-a4b8-4c81c3e4c147")
"aws-kms://arn:aws:kms:ca-central-1:111122223333:key/800d5768-3fd7-4edd-a4b8-4c81c3e4c147",
[]Opts{}...)

svc.client = &mockAWSClient{describeKeyFunc: func(input *kms.DescribeKeyInput) (*kms.DescribeKeyOutput, error) {
return nil, fmt.Errorf("failed to list keys")
Expand All @@ -150,7 +153,7 @@ func TestCreate(t *testing.T) {
})
require.NoError(t, err)

svc := New(awsSession, &mockMetrics{}, "")
svc := New(awsSession, &mockMetrics{}, "", []Opts{}...)

keyID := "key1"

Expand All @@ -163,6 +166,33 @@ func TestCreate(t *testing.T) {
require.Contains(t, result, keyID)
})

t.Run("success: with key alias prefix", func(t *testing.T) {
endpoint := localhost
awsSession, err := session.NewSession(&aws.Config{
Endpoint: &endpoint,
Region: aws.String("ca"),
CredentialsChainVerboseErrors: aws.Bool(true),
})
require.NoError(t, err)

svc := New(awsSession, &mockMetrics{}, "", WithKeyAliasPrefix("dummyKeyAlias"))

keyID := "key1"

svc.client = &mockAWSClient{
createKeyFunc: func(input *kms.CreateKeyInput) (*kms.CreateKeyOutput, error) {
return &kms.CreateKeyOutput{KeyMetadata: &kms.KeyMetadata{KeyId: &keyID}}, nil
},
createAliasFunc: func(input *kms.CreateAliasInput) (*kms.CreateAliasOutput, error) {
return &kms.CreateAliasOutput{}, nil
},
}

result, _, err := svc.Create(arieskms.ECDSAP256DER)
require.NoError(t, err)
require.Contains(t, result, keyID)
})

t.Run("key not supported", func(t *testing.T) {
endpoint := localhost
awsSession, err := session.NewSession(&aws.Config{
Expand All @@ -172,7 +202,7 @@ func TestCreate(t *testing.T) {
})
require.NoError(t, err)

svc := New(awsSession, &mockMetrics{}, "")
svc := New(awsSession, &mockMetrics{}, "", []Opts{}...)

_, _, err = svc.Create(arieskms.ED25519)
require.Error(t, err)
Expand All @@ -190,7 +220,7 @@ func TestGet(t *testing.T) {
})
require.NoError(t, err)

svc := New(awsSession, &mockMetrics{}, "")
svc := New(awsSession, &mockMetrics{}, "", []Opts{}...)

keyID, err := svc.Get("key1")
require.NoError(t, err)
Expand All @@ -210,7 +240,7 @@ func TestCreateAndPubKeyBytes(t *testing.T) {

keyID := "aws-kms://arn:aws:kms:ca-central-1:111122223333:key/800d5768-3fd7-4edd-a4b8-4c81c3e4c147"

svc := New(awsSession, &mockMetrics{}, "")
svc := New(awsSession, &mockMetrics{}, "", []Opts{}...)

svc.client = &mockAWSClient{
getPublicKeyFunc: func(input *kms.GetPublicKeyInput) (*kms.GetPublicKeyOutput, error) {
Expand Down Expand Up @@ -242,7 +272,7 @@ func TestSignMulti(t *testing.T) {
})
require.NoError(t, err)

svc := New(awsSession, &mockMetrics{}, "")
svc := New(awsSession, &mockMetrics{}, "", []Opts{}...)

_, err = svc.SignMulti(nil, nil)
require.Error(t, err)
Expand All @@ -259,7 +289,7 @@ func TestPubKeyBytes(t *testing.T) {
})
require.NoError(t, err)

svc := New(awsSession, &mockMetrics{}, "")
svc := New(awsSession, &mockMetrics{}, "", []Opts{}...)

svc.client = &mockAWSClient{getPublicKeyFunc: func(input *kms.GetPublicKeyInput) (*kms.GetPublicKeyOutput, error) {
signingAlgo := "ECDSA_SHA_256"
Expand All @@ -286,7 +316,7 @@ func TestPubKeyBytes(t *testing.T) {
})
require.NoError(t, err)

svc := New(awsSession, &mockMetrics{}, "")
svc := New(awsSession, &mockMetrics{}, "", []Opts{}...)

svc.client = &mockAWSClient{getPublicKeyFunc: func(input *kms.GetPublicKeyInput) (*kms.GetPublicKeyOutput, error) {
return nil, fmt.Errorf("failed to export public key")
Expand All @@ -307,7 +337,7 @@ func TestPubKeyBytes(t *testing.T) {
})
require.NoError(t, err)

svc := New(awsSession, &mockMetrics{}, "")
svc := New(awsSession, &mockMetrics{}, "", []Opts{}...)

_, _, err = svc.ExportPubKeyBytes("aws-kms://arn:aws:kms:key1")
require.Error(t, err)
Expand All @@ -321,6 +351,7 @@ type mockAWSClient struct {
verifyFunc func(input *kms.VerifyInput) (*kms.VerifyOutput, error)
describeKeyFunc func(input *kms.DescribeKeyInput) (*kms.DescribeKeyOutput, error)
createKeyFunc func(input *kms.CreateKeyInput) (*kms.CreateKeyOutput, error)
createAliasFunc func(input *kms.CreateAliasInput) (*kms.CreateAliasOutput, error)
}

func (m *mockAWSClient) Sign(input *kms.SignInput) (*kms.SignOutput, error) {
Expand Down Expand Up @@ -363,6 +394,14 @@ func (m *mockAWSClient) CreateKey(input *kms.CreateKeyInput) (*kms.CreateKeyOutp
return nil, nil //nolint:nilnil
}

func (m *mockAWSClient) CreateAlias(input *kms.CreateAliasInput) (*kms.CreateAliasOutput, error) {
if m.createAliasFunc != nil {
return m.createAliasFunc(input)
}

return nil, nil //nolint:nilnil
}

type mockMetrics struct{}

func (m *mockMetrics) SignCount() {
Expand Down
8 changes: 3 additions & 5 deletions test/bdd/go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ module github.com/trustbloc/kms/test/bdd
go 1.18

require (
github.com/coreos/go-oidc/v3 v3.1.0
github.com/cucumber/godog v0.10.0
github.com/google/uuid v1.3.0
github.com/greenpau/go-calculator v1.0.1
Expand All @@ -16,17 +15,13 @@ require (
github.com/hyperledger/aries-framework-go/component/storageutil v0.0.0-20220610133818-119077b0ec85
github.com/hyperledger/aries-framework-go/spi v0.0.0-20220614152730-3d817acfa48b
github.com/igor-pavlenko/httpsignatures-go v0.0.23
github.com/lafriks/go-shamir v1.1.0
github.com/ory/hydra-client-go v1.10.6
github.com/rs/xid v1.3.0
github.com/square/go-jose/v3 v3.0.0-20200630053402-0a67ce9b0693
github.com/teserakt-io/golang-ed25519 v0.0.0-20210104091850-3888c087a4c8
github.com/tidwall/gjson v1.9.3
github.com/trustbloc/auth v0.1.9-0.20220721161924-5a7b16c4282f
github.com/trustbloc/auth/spi/gnap v0.0.0-20220721161924-5a7b16c4282f
github.com/trustbloc/edge-core v0.1.8
github.com/trustbloc/kms v0.1.9-0.20220526151939-d46e46e8f7e1
golang.org/x/oauth2 v0.0.0-20220411215720-9780585627b5
)

require (
Expand All @@ -43,6 +38,7 @@ require (
github.com/cenkalti/backoff/v4 v4.1.3 // indirect
github.com/cespare/xxhash/v2 v2.1.2 // indirect
github.com/containerd/continuity v0.2.2 // indirect
github.com/coreos/go-oidc/v3 v3.1.0 // indirect
github.com/cucumber/gherkin-go/v11 v11.0.0 // indirect
github.com/cucumber/messages-go/v10 v10.0.3 // indirect
github.com/davecgh/go-spew v1.1.1 // indirect
Expand Down Expand Up @@ -107,6 +103,7 @@ require (
github.com/opencontainers/image-spec v1.0.3-0.20211202183452-c5a74bcca799 // indirect
github.com/opencontainers/runc v1.1.2 // indirect
github.com/opentracing/opentracing-go v1.2.0 // indirect
github.com/ory/hydra-client-go v1.10.6 // indirect
github.com/piprate/json-gold v0.4.1 // indirect
github.com/pkg/errors v0.9.1 // indirect
github.com/pmezard/go-difflib v1.0.0 // indirect
Expand Down Expand Up @@ -134,6 +131,7 @@ require (
go.mongodb.org/mongo-driver v1.9.1 // indirect
golang.org/x/crypto v0.0.0-20220525230936-793ad666bf5e // indirect
golang.org/x/net v0.0.0-20220127200216-cd36cc0744dd // indirect
golang.org/x/oauth2 v0.0.0-20220411215720-9780585627b5 // indirect
golang.org/x/sync v0.0.0-20220601150217-0de741cfad7f // indirect
golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a // indirect
golang.org/x/text v0.3.7 // indirect
Expand Down
Loading

0 comments on commit 50a50d5

Please sign in to comment.