Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: kms per profile & bdd for eddsa-rdfc-2022 #1766

Merged
merged 9 commits into from
Oct 1, 2024
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
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ ALPINE_IMAGE ?=alpine
OPENSSL_IMAGE ?=frapsoft/openssl
GOPROXY ?= https://proxy.golang.org

VC_FRAMEWORK_VERSION = 62cdfe76225e3bec435d678a331a064e602a4dcf
VC_FRAMEWORK_VERSION = a58759112df5dec505bb1bd37c1baa1c8fcd823c
KMS_FRAMEWORK_VERSION = 59c2830d27fd44f9a3a663242a4aa61544ce622e
DID_GO_VERSION = aa500e57d8bdf51c90c20d3a6c815fdc76f716c3
SIDE_TREE_VERSION = f4260aff710479ba5fa3f0c61b51d451d9041225
Expand Down
10 changes: 10 additions & 0 deletions cmd/vc-rest/startcmd/params.go
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,11 @@ const (
aliasPrefixFlagUsage = "alias prefix" +
commonEnvVarUsageText + aliasPrefixEnvKey

masterKeyFlagName = "local-kms-master-key"
masterKeyEnvKey = "VC_REST_LOCAL_KMS_MASTER_KEY"
masterKeyFlagUsage = "Local KMS master key" +
commonEnvVarUsageText + masterKeyEnvKey

// Linter gosec flags these as "potential hardcoded credentials". They are not, hence the nolint annotations.
kmsSecretsDatabaseTypeFlagName = "default-kms-secrets-database-type" //nolint: gosec
kmsSecretsDatabaseTypeEnvKey = "VC_REST_DEFAULT_KMS_SECRETS_DATABASE_TYPE" //nolint: gosec
Expand Down Expand Up @@ -490,6 +495,7 @@ type kmsParameters struct {
kmsSecretsDatabasePrefix string
secretLockKeyPath string
aliasPrefix string
masterKey string
}

// nolint: gocyclo,funlen
Expand Down Expand Up @@ -953,6 +959,8 @@ func getKMSParameters(cmd *cobra.Command) (*kmsParameters, error) {
secretLockKeyPath := cmdutils.GetUserSetOptionalVarFromString(cmd, secretLockKeyPathFlagName, secretLockKeyPathEnvKey)
aliasPrefix := cmdutils.GetUserSetOptionalVarFromString(cmd, aliasPrefixFlagName, aliasPrefixEnvKey)

masterKey := cmdutils.GetUserSetOptionalVarFromString(cmd, masterKeyFlagName, masterKeyEnvKey)

keyDatabaseType, err := cmdutils.GetUserSetVarFromString(cmd, kmsSecretsDatabaseTypeFlagName,
kmsSecretsDatabaseTypeEnvKey, kmsType != kms.Local)
if err != nil {
Expand All @@ -972,6 +980,7 @@ func getKMSParameters(cmd *cobra.Command) (*kmsParameters, error) {
kmsSecretsDatabaseURL: keyDatabaseURL,
kmsSecretsDatabasePrefix: keyDatabasePrefix,
aliasPrefix: aliasPrefix,
masterKey: masterKey,
}, nil
}

Expand Down Expand Up @@ -1150,6 +1159,7 @@ func createFlags(startCmd *cobra.Command) {
startCmd.Flags().String(kmsEndpointFlagName, "", kmsEndpointFlagUsage)
startCmd.Flags().String(secretLockKeyPathFlagName, "", secretLockKeyPathFlagUsage)
startCmd.Flags().String(aliasPrefixFlagName, "", aliasPrefixFlagUsage)
startCmd.Flags().String(masterKeyFlagName, "", masterKeyFlagUsage)
startCmd.Flags().String(kmsRegionFlagName, "", kmsRegionFlagUsage)
startCmd.Flags().StringP(tlsCertificateFlagName, "", "", tlsCertificateFlagUsage)
startCmd.Flags().StringP(tlsKeyFlagName, "", "", tlsKeyFlagUsage)
Expand Down
9 changes: 6 additions & 3 deletions cmd/vc-rest/startcmd/start.go
Original file line number Diff line number Diff line change
Expand Up @@ -450,7 +450,7 @@ func buildEchoHandler(

tlsConfig := &tls.Config{RootCAs: conf.RootCAs, MinVersion: tls.VersionTLS12}

defaultVCSKeyManager, err := kms.NewAriesKeyManager(&kms.Config{
defaultKmsConfig := kms.Config{
KMSType: conf.StartupParameters.kmsParameters.kmsType,
Endpoint: conf.StartupParameters.kmsParameters.kmsEndpoint,
Region: conf.StartupParameters.kmsParameters.kmsRegion,
Expand All @@ -460,12 +460,15 @@ func buildEchoHandler(
DBURL: conf.StartupParameters.dbParameters.databaseURL,
DBPrefix: conf.StartupParameters.dbParameters.databasePrefix,
AliasPrefix: conf.StartupParameters.kmsParameters.aliasPrefix,
}, metrics)
MasterKey: conf.StartupParameters.kmsParameters.masterKey,
}

defaultVCSKeyManager, err := kms.NewAriesKeyManager(&defaultKmsConfig, metrics)
if err != nil {
return nil, fmt.Errorf("failed to create default kms: %w", err)
}

kmsRegistry := kms.NewRegistry(defaultVCSKeyManager)
kmsRegistry := kms.NewRegistry(defaultVCSKeyManager, defaultKmsConfig, metrics)

var redisClient, redisClientNoTracing *redisclient.Client
if conf.StartupParameters.transientDataParams.storeType == redisStore {
Expand Down
4 changes: 3 additions & 1 deletion pkg/doc/vc/crypto/dataIntegrity.go
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,9 @@ func (c *Crypto) signCredentialLDPDataIntegrity(signerData *vc.Signer,
}

func (c *Crypto) getDataIntegritySignerInitializer(
dataIntegritySuiteType string, signer vc.SignerAlgorithm) (dataintegritysuite.SignerInitializer, error) {
dataIntegritySuiteType string,
signer vc.SignerAlgorithm,
) (dataintegritysuite.SignerInitializer, error) {
switch dataIntegritySuiteType { //nolint: exhaustive
case ecdsa2019.SuiteType, ecdsa2019.SuiteTypeNew:
return ecdsa2019.NewSignerInitializer(&ecdsa2019.SignerInitializerOptions{
Expand Down
31 changes: 22 additions & 9 deletions pkg/kms/arieskms.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
import (
"context"
"fmt"
"io"
"strings"
"time"

Expand Down Expand Up @@ -125,7 +126,10 @@
}

func createLocalKMS(cfg *Config) (api.Suite, error) {
secretLockService, err := createLocalSecretLock(cfg.SecretLockKeyPath)
secretLockService, err := createLocalSecretLock(
cfg.SecretLockKeyPath,
cfg.MasterKey,
)
if err != nil {
return nil, err
}
Expand Down Expand Up @@ -187,14 +191,23 @@
return signer.NewKMSSigner(fks, signatureType, km.metrics), nil
}

func createLocalSecretLock(keyPath string) (secretlock.Service, error) {
if keyPath == "" {
return nil, fmt.Errorf("no key defined for local secret lock")
}

primaryKeyReader, err := local.MasterKeyFromPath(keyPath)
if err != nil {
return nil, err
func createLocalSecretLock(
keyPath string,
kmsMasterKey string,
) (secretlock.Service, error) {
var err error
var primaryKeyReader io.Reader

if kmsMasterKey != "" {
primaryKeyReader = strings.NewReader(kmsMasterKey)
} else {
if keyPath == "" {
return nil, fmt.Errorf("no key defined for local secret lock")

Check warning on line 205 in pkg/kms/arieskms.go

View check run for this annotation

Codecov / codecov/patch

pkg/kms/arieskms.go#L205

Added line #L205 was not covered by tests
}
primaryKeyReader, err = local.MasterKeyFromPath(keyPath)
if err != nil {
return nil, err
}
}

secretLock, err := local.NewService(primaryKeyReader, nil)
Expand Down
44 changes: 42 additions & 2 deletions pkg/kms/arieskms_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import (
"crypto/rand"
"crypto/sha256"
"encoding/base64"
"io"
"net/http"
"os"
"testing"
Expand Down Expand Up @@ -87,6 +88,26 @@ func TestNewLocalKeyManager(t *testing.T) {
require.NoError(t, err)
})

t.Run("Success env", func(t *testing.T) {
pool, mongoDBResource := startMongoDBContainer(t)

defer func() {
require.NoError(t, pool.Purge(mongoDBResource), "failed to purge MongoDB resource")
}()

km, err := kms.NewAriesKeyManager(&kms.Config{
KMSType: kms.Local,
SecretLockKeyPath: secretLockKeyFile,
DBType: "mongodb",
DBURL: mongoDBConnString,
DBPrefix: "test",
MasterKey: "00kIMo3wwfp1r8OOR8QMSkyIByY8ZHBKJy4l0u2i9f4=",
}, nil)

require.NoError(t, err)
require.NotNil(t, km)
})

t.Run("Fail mongodb", func(t *testing.T) {
km, err := kms.NewAriesKeyManager(&kms.Config{
KMSType: kms.Local,
Expand Down Expand Up @@ -157,10 +178,10 @@ func TestNewAWSKeyManager(t *testing.T) {
require.NotNil(t, km)
require.NoError(t, err)

_, _, err = km.CreateJWKKey(arieskms.ED25519Type)
_, _, err = km.CreateJWKKey(arieskms.NISTP384ECDHKW)

require.Error(t, err)
require.Contains(t, err.Error(), "key not supported ED25519")
require.Contains(t, err.Error(), "key not supported NISTP384ECDHKW")
})
}

Expand Down Expand Up @@ -227,6 +248,25 @@ func startMongoDBContainer(t *testing.T) (*dctest.Pool, *dctest.Resource) {
return pool, mongoDBResource
}

func TestGenerateMasterKey(t *testing.T) {
masterKey, err := GenerateMasterKey(32) // aes-256
require.NoError(t, err)
require.Len(t, masterKey, 32)

masterKeyBase64 := base64.URLEncoding.EncodeToString(masterKey)
require.NotEmpty(t, masterKeyBase64)
}

// GenerateMasterKey generates a random master key of specified length.
func GenerateMasterKey(length int) ([]byte, error) {
masterKey := make([]byte, length)
_, err := io.ReadFull(rand.Reader, masterKey)
if err != nil {
return nil, err
}
return masterKey, nil
}

func waitForMongoDBToBeUp() error {
return backoff.Retry(pingMongoDB, backoff.WithMaxRetries(backoff.NewConstantBackOff(time.Second), 30))
}
Expand Down
2 changes: 2 additions & 0 deletions pkg/kms/aws/service.go
Original file line number Diff line number Diff line change
Expand Up @@ -351,6 +351,8 @@
var keySpec types.KeySpec

switch string(kt) {
case arieskms.ED25519:
keySpec = types.KeySpecEccNistP256

Check warning on line 355 in pkg/kms/aws/service.go

View check run for this annotation

Codecov / codecov/patch

pkg/kms/aws/service.go#L354-L355

Added lines #L354 - L355 were not covered by tests
case arieskms.ECDSAP256DER:
keySpec = types.KeySpecEccNistP256
case arieskms.ECDSAP384DER:
Expand Down
2 changes: 1 addition & 1 deletion pkg/kms/aws/service_mocks.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

16 changes: 6 additions & 10 deletions pkg/kms/aws/service_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -354,9 +354,9 @@ func TestCreate(t *testing.T) {

svc := New(awsConfig, metric, "", []Opts{}...)

_, _, err := svc.Create(arieskms.ED25519)
_, _, err := svc.Create(arieskms.X25519ECDHKW)
require.Error(t, err)
require.Contains(t, err.Error(), "key not supported ED25519")
require.Contains(t, err.Error(), "key not supported X25519ECDHKW")
})

t.Run("create error", func(t *testing.T) {
Expand Down Expand Up @@ -555,22 +555,18 @@ func TestCreateAndPubKeyBytes(t *testing.T) {

svc := New(&awsConfig, metric, "", []Opts{}...)

_, _, err := svc.CreateAndExportPubKeyBytes(arieskms.ED25519)
_, _, err := svc.CreateAndExportPubKeyBytes(arieskms.X25519ECDHKW)
require.Error(t, err)
require.Contains(t, err.Error(), "key not supported ED25519")
require.Contains(t, err.Error(), "key not supported X25519ECDHKW")

suite := NewSuite(&awsConfig, metric, "", []Opts{}...)

creator, err := suite.RawKeyCreator()
require.NoError(t, err)

_, err = creator.Create(arieskms.ED25519Type)
_, err = creator.Create(arieskms.X25519ECDHKW)
require.Error(t, err)
require.Contains(t, err.Error(), "key not supported ED25519")

_, _, err = creator.CreateRaw(arieskms.ED25519Type)
require.Error(t, err)
require.Contains(t, err.Error(), "key not supported ED25519")
require.Contains(t, err.Error(), "key not supported X25519ECDHKW")
})

t.Run("export error", func(t *testing.T) {
Expand Down
3 changes: 2 additions & 1 deletion pkg/kms/kms.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ const (

// Config configure kms that stores signing keys.
type Config struct {
KMSType Type
KMSType Type `json:"kmsType"`
Endpoint string
Region string
AliasPrefix string
Expand All @@ -38,6 +38,7 @@ type Config struct {
DBType string
DBURL string
DBPrefix string
MasterKey string
}

type VCSKeyManager interface {
Expand Down
2 changes: 1 addition & 1 deletion pkg/kms/mocks/kms_mocks.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

27 changes: 18 additions & 9 deletions pkg/kms/registry.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,17 +6,21 @@

package kms

import (
"fmt"
)

type Registry struct {
defaultVCSKeyManager VCSKeyManager
defaultVCSKeyManager VCSKeyManager
defaultConfig Config
defaultMetricProvider metricsProvider
}

func NewRegistry(defaultVCSKeyManager VCSKeyManager) *Registry {
func NewRegistry(
defaultVCSKeyManager VCSKeyManager,
defaultKmsConfig Config,
defaultMetricProvider metricsProvider,
) *Registry {
return &Registry{
defaultVCSKeyManager: defaultVCSKeyManager,
defaultConfig: defaultKmsConfig,
defaultVCSKeyManager: defaultVCSKeyManager,
defaultMetricProvider: defaultMetricProvider,
}
}

Expand All @@ -25,6 +29,11 @@
return r.defaultVCSKeyManager, nil
}

// TODO handle kms per profile creation
return nil, fmt.Errorf("unsupported profile kms")
cfgCopy := r.defaultConfig
cfgCopy.KMSType = config.KMSType
if config.MasterKey != "" {
cfgCopy.MasterKey = config.MasterKey

Check warning on line 35 in pkg/kms/registry.go

View check run for this annotation

Codecov / codecov/patch

pkg/kms/registry.go#L35

Added line #L35 was not covered by tests
}

return NewAriesKeyManager(&cfgCopy, r.defaultMetricProvider)
}
15 changes: 13 additions & 2 deletions pkg/kms/registry_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,16 +15,27 @@ import (
)

func TestNewRegistry(t *testing.T) {
r := kms.NewRegistry(nil)
r := kms.NewRegistry(nil, kms.Config{}, nil)
require.NotNil(t, r)
}

func TestRegistry_GetKeyManager(t *testing.T) {
t.Run("Default config local kms", func(t *testing.T) {
r := kms.NewRegistry(nil)
r := kms.NewRegistry(nil, kms.Config{KMSType: kms.Local}, nil)
require.NotNil(t, r)

_, err := r.GetKeyManager(nil)
require.NoError(t, err)
})

t.Run("Fallback kms", func(t *testing.T) {
r := kms.NewRegistry(nil, kms.Config{KMSType: kms.Local}, nil)
require.NotNil(t, r)

_, err := r.GetKeyManager(&kms.Config{
KMSType: "aws",
})

require.NoError(t, err)
})
}
Loading
Loading