Skip to content

Commit

Permalink
Add checks to see if current seal generation is in middle of rewrappi…
Browse files Browse the repository at this point in the history
…ng (#22692)

* Add checks to see if current seal generation is in middle of rewrapping

* Check for rewrap flag only if thr previous configuration is not shamir
  • Loading branch information
divyapola5 committed Aug 31, 2023
1 parent 3e0baa9 commit cdf6bf0
Show file tree
Hide file tree
Showing 5 changed files with 216 additions and 42 deletions.
8 changes: 7 additions & 1 deletion command/operator_diagnose.go
Original file line number Diff line number Diff line change
Expand Up @@ -434,13 +434,19 @@ func (c *OperatorDiagnoseCommand) offlineDiagnostics(ctx context.Context) error
sealcontext, sealspan := diagnose.StartSpan(ctx, "Create Vault Server Configuration Seals")

var setSealResponse *SetSealResponse
var hasPartialPaths bool
existingSealGenerationInfo, err := vault.PhysicalSealGenInfo(sealcontext, *backend)
if err != nil {
diagnose.Fail(sealcontext, fmt.Sprintf("Unable to get Seal genration information from storage: %s.", err.Error()))
goto SEALFAIL
}

setSealResponse, err = setSeal(server, config, make([]string, 0), make(map[string]string), existingSealGenerationInfo, server.logger)
hasPartialPaths, err = hasPartiallyWrappedPaths(context.Background(), *backend)
if err != nil {
diagnose.Fail(sealcontext, fmt.Sprintf("Cannot determine if there are parrtially seal wrapped entries in storage: %s.", err.Error()))
goto SEALFAIL
}
setSealResponse, err = setSeal(server, config, make([]string, 0), make(map[string]string), existingSealGenerationInfo, hasPartialPaths)
if err != nil {
diagnose.Advise(ctx, "For assistance with the seal stanza, see the Vault configuration documentation.")
diagnose.Fail(sealcontext, fmt.Sprintf("Seal creation resulted in the following error: %s.", err.Error()))
Expand Down
54 changes: 38 additions & 16 deletions command/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -560,13 +560,19 @@ func (c *ServerCommand) runRecoveryMode() int {
return 1
}

existingSealGenenrationInfo, err := vault.PhysicalSealGenInfo(context.Background(), backend)
ctx := context.Background()
existingSealGenerationInfo, err := vault.PhysicalSealGenInfo(ctx, backend)
if err != nil {
c.UI.Error(fmt.Sprintf("Error getting seal generation info: %v", err))
return 1
}

setSealResponse, err := setSeal(c, config, infoKeys, info, existingSealGenenrationInfo, c.logger)
hasPartialPaths, err := hasPartiallyWrappedPaths(ctx, backend)
if err != nil {
c.UI.Error(fmt.Sprintf("Cannot determine if there are parrtially seal wrapped entries in storage: %v", err))
return 1
}
setSealResponse, err := setSeal(c, config, infoKeys, info, existingSealGenerationInfo, hasPartialPaths)
if err != nil {
c.UI.Error(err.Error())
return 1
Expand All @@ -579,7 +585,7 @@ func (c *ServerCommand) runRecoveryMode() int {

// Ensure that the seal finalizer is called, even if using verify-only
defer func() {
err = barrierSeal.Finalize(context.Background())
err = barrierSeal.Finalize(ctx)
if err != nil {
c.UI.Error(fmt.Sprintf("Error finalizing seals: %v", err))
}
Expand All @@ -605,7 +611,7 @@ func (c *ServerCommand) runRecoveryMode() int {
}
}

if err := core.InitializeRecovery(context.Background()); err != nil {
if err := core.InitializeRecovery(ctx); err != nil {
c.UI.Error(fmt.Sprintf("Error initializing core in recovery mode: %s", err))
return 1
}
Expand Down Expand Up @@ -706,7 +712,7 @@ func (c *ServerCommand) runRecoveryMode() int {
}

if sealConfigError != nil {
init, err := core.InitializedLocally(context.Background())
init, err := core.InitializedLocally(ctx)
if err != nil {
c.UI.Error(fmt.Sprintf("Error checking if core is initialized: %v", err))
return 1
Expand Down Expand Up @@ -1223,13 +1229,19 @@ func (c *ServerCommand) Run(args []string) int {
infoKeys = append(infoKeys, expKey)
}

existingSealGenenrationInfo, err := vault.PhysicalSealGenInfo(context.Background(), backend)
ctx := context.Background()
existingSealGenerationInfo, err := vault.PhysicalSealGenInfo(ctx, backend)
if err != nil {
c.UI.Error(fmt.Sprintf("Error getting seal generation info: %v", err))
return 1
}

setSealResponse, err := setSeal(c, config, infoKeys, info, existingSealGenenrationInfo, c.logger)
hasPartialPaths, err := hasPartiallyWrappedPaths(ctx, backend)
if err != nil {
c.UI.Error(fmt.Sprintf("Cannot determine if there are parrtially seal wrapped entries in storage: %v", err))
return 1
}
setSealResponse, err := setSeal(c, config, infoKeys, info, existingSealGenerationInfo, hasPartialPaths)
if err != nil {
c.UI.Error(err.Error())
return 1
Expand All @@ -1239,7 +1251,7 @@ func (c *ServerCommand) Run(args []string) int {
seal := seal // capture range variable
// Ensure that the seal finalizer is called, even if using verify-only
defer func(seal *vault.Seal) {
err = (*seal).Finalize(context.Background())
err = (*seal).Finalize(ctx)
if err != nil {
c.UI.Error(fmt.Sprintf("Error finalizing seals: %v", err))
}
Expand Down Expand Up @@ -1489,14 +1501,14 @@ func (c *ServerCommand) Run(args []string) int {
// uninitialized. Once one server initializes the storage backend, this
// goroutine will pick up the unseal keys and unseal this instance.
if !core.IsInSealMigrationMode() {
go runUnseal(c, core, context.Background())
go runUnseal(c, core, ctx)
}

// When the underlying storage is raft, kick off retry join if it was specified
// in the configuration
// TODO: Should we also support retry_join for ha_storage?
if config.Storage.Type == storageTypeRaft {
if err := core.InitiateRetryJoin(context.Background()); err != nil {
if err := core.InitiateRetryJoin(ctx); err != nil {
c.UI.Error(fmt.Sprintf("Failed to initiate raft retry join, %q", err.Error()))
return 1
}
Expand Down Expand Up @@ -1542,7 +1554,7 @@ func (c *ServerCommand) Run(args []string) int {
}

if setSealResponse.sealConfigError != nil {
init, err := core.InitializedLocally(context.Background())
init, err := core.InitializedLocally(ctx)
if err != nil {
c.UI.Error(fmt.Sprintf("Error checking if core is initialized: %v", err))
return 1
Expand Down Expand Up @@ -2532,7 +2544,7 @@ func (r *SetSealResponse) getCreatedSeals() []*vault.Seal {

// setSeal return barrierSeal, barrierWrapper, unwrapSeal, all the created seals, and all the provided seals from the configs so we can close them in Run
// The two errors are the sealConfigError and the regular error
func setSeal(c *ServerCommand, config *server.Config, infoKeys []string, info map[string]string, existingSealGenerationInfo *vaultseal.SealGenerationInfo, sealLogger hclog.Logger) (*SetSealResponse, error) {
func setSeal(c *ServerCommand, config *server.Config, infoKeys []string, info map[string]string, existingSealGenerationInfo *vaultseal.SealGenerationInfo, hasPartiallyWrappedPaths bool) (*SetSealResponse, error) {
if c.flagDevAutoSeal {
access, _ := vaultseal.NewTestSeal(nil)
barrierSeal := vault.NewAutoSeal(access)
Expand Down Expand Up @@ -2654,7 +2666,7 @@ func setSeal(c *ServerCommand, config *server.Config, infoKeys []string, info ma
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Compute seal generation

sealGenerationInfo, err := c.computeSealGenerationInfo(existingSealGenerationInfo, allSealKmsConfigs)
sealGenerationInfo, err := c.computeSealGenerationInfo(existingSealGenerationInfo, allSealKmsConfigs, hasPartiallyWrappedPaths)
if err != nil {
return nil, err
}
Expand All @@ -2678,6 +2690,7 @@ func setSeal(c *ServerCommand, config *server.Config, infoKeys []string, info ma
var barrierSeal vault.Seal
var unwrapSeal vault.Seal

sealLogger := c.logger
switch {
case len(enabledSealWrappers) == 0:
return nil, errors.New("no enabled Seals in configuration")
Expand Down Expand Up @@ -2723,7 +2736,7 @@ func setSeal(c *ServerCommand, config *server.Config, infoKeys []string, info ma
}, nil
}

func (c *ServerCommand) computeSealGenerationInfo(existingSealGenInfo *vaultseal.SealGenerationInfo, sealConfigs []*configutil.KMS) (*vaultseal.SealGenerationInfo, error) {
func (c *ServerCommand) computeSealGenerationInfo(existingSealGenInfo *vaultseal.SealGenerationInfo, sealConfigs []*configutil.KMS, hasPartiallyWrappedPaths bool) (*vaultseal.SealGenerationInfo, error) {
generation := uint64(1)

if existingSealGenInfo != nil {
Expand All @@ -2732,7 +2745,7 @@ func (c *ServerCommand) computeSealGenerationInfo(existingSealGenInfo *vaultseal
}
generation = existingSealGenInfo.Generation + 1
}
c.logger.Info("incrementing seal geneneration", "generation", generation)
c.logger.Info("incrementing seal generation", "generation", generation)

// If the stored copy doesn't match the current configuration, we introduce a new generation
// which keeps track if a rewrap of all CSPs and seal wrapped values has completed (initially false).
Expand All @@ -2741,14 +2754,23 @@ func (c *ServerCommand) computeSealGenerationInfo(existingSealGenInfo *vaultseal
Seals: sealConfigs,
}

err := newSealGenInfo.Validate(existingSealGenInfo)
err := newSealGenInfo.Validate(existingSealGenInfo, hasPartiallyWrappedPaths)
if err != nil {
return nil, err
}

return newSealGenInfo, nil
}

func hasPartiallyWrappedPaths(ctx context.Context, backend physical.Backend) (bool, error) {
paths, err := vault.GetPartiallySealWrappedPaths(ctx, backend)
if err != nil {
return false, err
}

return len(paths) > 0, nil
}

func initHaBackend(c *ServerCommand, config *server.Config, coreConfig *vault.CoreConfig, backend physical.Backend) (bool, error) {
// Initialize the separate HA storage backend, if it exists
var ok bool
Expand Down

0 comments on commit cdf6bf0

Please sign in to comment.