diff --git a/internal/kms/const.go b/internal/kms/const.go index bbf37cbb5..0dff8fa30 100644 --- a/internal/kms/const.go +++ b/internal/kms/const.go @@ -48,6 +48,9 @@ const ( // KeyPurposeRootKey is used as the root key KeyPurposeRootKey + + // KeyPurpose is used for wrapping BSR keys + KeyPurposeBsr ) // String returns the key purpose cast as a string, just so it can be called as @@ -74,6 +77,8 @@ func (k KeyPurpose) String() string { return "audit" case KeyPurposeRootKey: return "rootKey" + case KeyPurposeBsr: + return "bsr" default: return "unknown" } diff --git a/internal/kms/external_wrappers.go b/internal/kms/external_wrappers.go index 86185e190..669e50ad1 100644 --- a/internal/kms/external_wrappers.go +++ b/internal/kms/external_wrappers.go @@ -13,6 +13,7 @@ type ExternalWrappers struct { root wrapping.Wrapper workerAuth wrapping.Wrapper recovery wrapping.Wrapper + bsr wrapping.Wrapper } // Root returns the wrapper for root keys @@ -29,3 +30,8 @@ func (e *ExternalWrappers) WorkerAuth() wrapping.Wrapper { func (e *ExternalWrappers) Recovery() wrapping.Wrapper { return e.recovery } + +// Bsr returns the wrapper for BSR operations +func (e *ExternalWrappers) Bsr() wrapping.Wrapper { + return e.bsr +} diff --git a/internal/kms/external_wrappers_test.go b/internal/kms/external_wrappers_test.go index bb2e3352e..38866cdcb 100644 --- a/internal/kms/external_wrappers_test.go +++ b/internal/kms/external_wrappers_test.go @@ -24,14 +24,21 @@ func TestExternalWrappers(t *testing.T) { recoveryWrapper := db.TestWrapper(t) workerAuthWrapper := db.TestWrapper(t) workerAuthStorageWrapper := db.TestWrapper(t) + bsrWrapper := db.TestWrapper(t) k := TestKms(t, conn, rootWrapper) - err := k.AddExternalWrappers(testCtx, WithRecoveryWrapper(recoveryWrapper), WithWorkerAuthWrapper(workerAuthWrapper), WithWorkerAuthStorageWrapper(workerAuthStorageWrapper)) + err := k.AddExternalWrappers(testCtx, + WithRecoveryWrapper(recoveryWrapper), + WithWorkerAuthWrapper(workerAuthWrapper), + WithWorkerAuthStorageWrapper(workerAuthStorageWrapper), + WithBsrWrapper(bsrWrapper), + ) require.NoError(err) assert.Equal(rootWrapper, k.GetExternalWrappers(testCtx).Root()) assert.Equal(recoveryWrapper, k.GetExternalWrappers(testCtx).Recovery()) assert.Equal(workerAuthWrapper, k.GetExternalWrappers(testCtx).WorkerAuth()) + assert.Equal(bsrWrapper, k.GetExternalWrappers(testCtx).Bsr()) err = k.AddExternalWrappers(testCtx, WithRootWrapper(&invalidWrapper{})) assert.Error(err) @@ -39,6 +46,8 @@ func TestExternalWrappers(t *testing.T) { assert.Error(err) err = k.AddExternalWrappers(testCtx, WithWorkerAuthWrapper(&invalidWrapper{})) assert.Error(err) + err = k.AddExternalWrappers(testCtx, WithBsrWrapper(&invalidWrapper{})) + assert.Error(err) } type invalidWrapper struct { diff --git a/internal/kms/kms.go b/internal/kms/kms.go index 15e15c3ed..6cd08830d 100644 --- a/internal/kms/kms.go +++ b/internal/kms/kms.go @@ -104,6 +104,11 @@ func (k *Kms) AddExternalWrappers(ctx context.Context, opt ...Option) error { return errors.Wrap(ctx, err, op, errors.WithMsg("unable to add recovery wrapper")) } } + if opts.withBsrWrapper != nil { + if err := k.underlying.AddExternalWrapper(ctx, wrappingKms.KeyPurpose(KeyPurposeBsr.String()), opts.withBsrWrapper); err != nil { + return errors.Wrap(ctx, err, op, errors.WithMsg("unable to add bsr wrapper")) + } + } return nil } @@ -140,6 +145,9 @@ func (k *Kms) GetExternalWrappers(ctx context.Context) *ExternalWrappers { if recovery, err := k.underlying.GetExternalWrapper(ctx, wrappingKms.KeyPurpose(KeyPurposeRecovery.String())); err == nil { ret.recovery = recovery } + if bsr, err := k.underlying.GetExternalWrapper(ctx, wrappingKms.KeyPurpose(KeyPurposeBsr.String())); err == nil { + ret.bsr = bsr + } return ret } @@ -594,8 +602,12 @@ func stdNewKmsPurposes() []wrappingKms.KeyPurpose { for _, p := range ValidDekPurposes() { purposes = append(purposes, wrappingKms.KeyPurpose(p.String())) } - purposes = append(purposes, wrappingKms.KeyPurpose(KeyPurposeWorkerAuth.String()), wrappingKms.KeyPurpose(KeyPurposeWorkerAuthStorage.String()), - wrappingKms.KeyPurpose(KeyPurposeRecovery.String())) + purposes = append(purposes, + wrappingKms.KeyPurpose(KeyPurposeWorkerAuth.String()), + wrappingKms.KeyPurpose(KeyPurposeWorkerAuthStorage.String()), + wrappingKms.KeyPurpose(KeyPurposeRecovery.String()), + wrappingKms.KeyPurpose(KeyPurposeBsr.String()), + ) return purposes } diff --git a/internal/kms/kms_test.go b/internal/kms/kms_test.go index cee8bfcf3..17cb26f9d 100644 --- a/internal/kms/kms_test.go +++ b/internal/kms/kms_test.go @@ -56,8 +56,12 @@ func Test_New(t *testing.T) { for _, p := range ValidDekPurposes() { purposes = append(purposes, wrappingKms.KeyPurpose(p.String())) } - purposes = append(purposes, wrappingKms.KeyPurpose(KeyPurposeWorkerAuth.String()), - wrappingKms.KeyPurpose(KeyPurposeWorkerAuthStorage.String()), wrappingKms.KeyPurpose(KeyPurposeRecovery.String())) + purposes = append(purposes, + wrappingKms.KeyPurpose(KeyPurposeWorkerAuth.String()), + wrappingKms.KeyPurpose(KeyPurposeWorkerAuthStorage.String()), + wrappingKms.KeyPurpose(KeyPurposeRecovery.String()), + wrappingKms.KeyPurpose(KeyPurposeBsr.String()), + ) wrapped, err := wrappingKms.New(db.NewChangeSafeDbwReader(rw), db.NewChangeSafeDbwWriter(rw), purposes) require.NoError(t, err) diff --git a/internal/kms/options.go b/internal/kms/options.go index 55e393aec..a13fb2730 100644 --- a/internal/kms/options.go +++ b/internal/kms/options.go @@ -29,6 +29,7 @@ type options struct { withWorkerAuthWrapper wrapping.Wrapper withWorkerAuthStorageWrapper wrapping.Wrapper withRecoveryWrapper wrapping.Wrapper + withBsrWrapper wrapping.Wrapper withOrderByVersion db.OrderBy withKeyId string withScopeIds []string @@ -81,6 +82,13 @@ func WithRecoveryWrapper(w wrapping.Wrapper) Option { } } +// WithBsrWrapper sets the external Bsr wrapper for a KMS +func WithBsrWrapper(w wrapping.Wrapper) Option { + return func(o *options) { + o.withBsrWrapper = w + } +} + // WithOrderByVersion provides an option to specify ordering by the // CreateTime field. func WithOrderByVersion(orderBy db.OrderBy) Option {