2019-10-15 04:55:31 +00:00
|
|
|
package vault
|
|
|
|
|
|
|
|
import (
|
|
|
|
"context"
|
2021-05-11 17:12:54 +00:00
|
|
|
"fmt"
|
2019-11-07 16:54:34 +00:00
|
|
|
|
2021-07-16 00:17:31 +00:00
|
|
|
"github.com/hashicorp/go-secure-stdlib/base62"
|
2019-10-15 04:55:31 +00:00
|
|
|
"go.uber.org/atomic"
|
|
|
|
)
|
|
|
|
|
|
|
|
// GenerateRecoveryTokenStrategy is the strategy used to generate a
|
|
|
|
// recovery token
|
|
|
|
func GenerateRecoveryTokenStrategy(token *atomic.String) GenerateRootStrategy {
|
|
|
|
return &generateRecoveryToken{token: token}
|
|
|
|
}
|
|
|
|
|
|
|
|
// generateRecoveryToken implements the GenerateRootStrategy and is in
|
|
|
|
// charge of creating recovery tokens.
|
|
|
|
type generateRecoveryToken struct {
|
|
|
|
token *atomic.String
|
|
|
|
}
|
|
|
|
|
2019-10-23 16:52:28 +00:00
|
|
|
func (g *generateRecoveryToken) authenticate(ctx context.Context, c *Core, combinedKey []byte) error {
|
2020-10-23 18:16:04 +00:00
|
|
|
key, err := c.unsealKeyToMasterKeyPostUnseal(ctx, combinedKey)
|
2019-10-23 16:52:28 +00:00
|
|
|
if err != nil {
|
2021-05-11 17:12:54 +00:00
|
|
|
return fmt.Errorf("unable to authenticate: %w", err)
|
2019-10-23 16:52:28 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// Use the retrieved master key to unseal the barrier
|
|
|
|
if err := c.barrier.Unseal(ctx, key); err != nil {
|
2021-05-11 17:12:54 +00:00
|
|
|
return fmt.Errorf("recovery operation token generation failed, cannot unseal barrier: %w", err)
|
2019-10-23 16:52:28 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
for _, v := range c.postRecoveryUnsealFuncs {
|
|
|
|
if err := v(); err != nil {
|
2021-05-11 17:12:54 +00:00
|
|
|
return fmt.Errorf("failed to run post unseal func: %w", err)
|
2019-10-23 16:52:28 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
2019-10-15 04:55:31 +00:00
|
|
|
func (g *generateRecoveryToken) generate(ctx context.Context, c *Core) (string, func(), error) {
|
|
|
|
id, err := base62.Random(TokenLength)
|
|
|
|
if err != nil {
|
|
|
|
return "", nil, err
|
|
|
|
}
|
|
|
|
token := "r." + id
|
|
|
|
g.token.Store(token)
|
|
|
|
|
|
|
|
return token, func() { g.token.Store("") }, nil
|
|
|
|
}
|