package transit import ( "context" "fmt" "strings" "github.com/hashicorp/vault/sdk/framework" "github.com/hashicorp/vault/sdk/helper/keysutil" "github.com/hashicorp/vault/sdk/logical" ) func Factory(ctx context.Context, conf *logical.BackendConfig) (logical.Backend, error) { b, err := Backend(ctx, conf) if err != nil { return nil, err } if err := b.Setup(ctx, conf); err != nil { return nil, err } return b, nil } func Backend(ctx context.Context, conf *logical.BackendConfig) (*backend, error) { var b backend b.Backend = &framework.Backend{ PathsSpecial: &logical.Paths{ SealWrapStorage: []string{ "archive/", "policy/", }, }, Paths: []*framework.Path{ // Rotate/Config needs to come before Keys // as the handler is greedy b.pathConfig(), b.pathRotate(), b.pathRewrap(), b.pathKeys(), b.pathListKeys(), b.pathExportKeys(), b.pathEncrypt(), b.pathDecrypt(), b.pathDatakey(), b.pathRandom(), b.pathHash(), b.pathHMAC(), b.pathSign(), b.pathVerify(), b.pathBackup(), b.pathRestore(), b.pathTrim(), b.pathCacheConfig(), }, Secrets: []*framework.Secret{}, Invalidate: b.invalidate, BackendType: logical.TypeLogical, } // determine cacheSize to use. Defaults to 0 which means unlimited cacheSize := 0 useCache := !conf.System.CachingDisabled() if useCache { var err error cacheSize, err = GetCacheSizeFromStorage(ctx, conf.StorageView) if err != nil { return nil, fmt.Errorf("Error retrieving cache size from storage: %w", err) } } var err error b.lm, err = keysutil.NewLockManager(useCache, cacheSize) if err != nil { return nil, err } return &b, nil } type backend struct { *framework.Backend lm *keysutil.LockManager } func GetCacheSizeFromStorage(ctx context.Context, s logical.Storage) (int, error) { size := 0 entry, err := s.Get(ctx, "config/cache") if err != nil { return 0, err } if entry != nil { var storedCache configCache if err := entry.DecodeJSON(&storedCache); err != nil { return 0, err } size = storedCache.Size } return size, nil } func (b *backend) invalidate(_ context.Context, key string) { if b.Logger().IsDebug() { b.Logger().Debug("invalidating key", "key", key) } switch { case strings.HasPrefix(key, "policy/"): name := strings.TrimPrefix(key, "policy/") b.lm.InvalidatePolicy(name) } }