Rename master key to root key (#13324)

* See what it looks like to replace "master key" with "root key".  There are two places that would require more challenging code changes: the storage path `core/master`, and its contents (the JSON-serialized EncodedKeyringtructure.)

* Restore accidentally deleted line

* Add changelog

* Update root->recovery

* Fix test

Co-authored-by: Nick Cabatoff <ncabatoff@hashicorp.com>
This commit is contained in:
Jim Kalafut 2021-12-06 17:12:20 -08:00 committed by GitHub
parent 04d634d9d2
commit 22c4ae5933
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
23 changed files with 182 additions and 179 deletions

3
changelog/13324.txt Normal file
View File

@ -0,0 +1,3 @@
```release-note:improvement
core: Replace "master key" terminology with "root key"
```

View File

@ -57,10 +57,10 @@ Usage: vault operator init [options]
same storage backend in HA mode, you only need to initialize one Vault to same storage backend in HA mode, you only need to initialize one Vault to
initialize the storage backend. initialize the storage backend.
During initialization, Vault generates an in-memory master key and applies During initialization, Vault generates an in-memory root key and applies
Shamir's secret sharing algorithm to disassemble that master key into a Shamir's secret sharing algorithm to disassemble that root key into a
configuration number of key shares such that a configurable subset of those configuration number of key shares such that a configurable subset of those
key shares must come together to regenerate the master key. These keys are key shares must come together to regenerate the root key. These keys are
often called "unseal keys" in Vault's documentation. often called "unseal keys" in Vault's documentation.
This command cannot be run against an already-initialized Vault cluster. This command cannot be run against an already-initialized Vault cluster.
@ -105,7 +105,7 @@ func (c *OperatorInitCommand) Flags() *FlagSets {
Target: &c.flagKeyShares, Target: &c.flagKeyShares,
Default: defKeyShares, Default: defKeyShares,
Completion: complete.PredictAnything, Completion: complete.PredictAnything,
Usage: "Number of key shares to split the generated master key into. " + Usage: "Number of key shares to split the generated root key into. " +
"This is the number of \"unseal keys\" to generate.", "This is the number of \"unseal keys\" to generate.",
}) })
@ -115,7 +115,7 @@ func (c *OperatorInitCommand) Flags() *FlagSets {
Target: &c.flagKeyThreshold, Target: &c.flagKeyThreshold,
Default: defKeyThreshold, Default: defKeyThreshold,
Completion: complete.PredictAnything, Completion: complete.PredictAnything,
Usage: "Number of key shares required to reconstruct the master key. " + Usage: "Number of key shares required to reconstruct the root key. " +
"This must be less than or equal to -key-shares.", "This must be less than or equal to -key-shares.",
}) })
@ -447,8 +447,8 @@ func (c *OperatorInitCommand) init(client *api.Client, req *api.InitRequest) int
c.UI.Output("") c.UI.Output("")
c.UI.Output(wrapAtLength(fmt.Sprintf( c.UI.Output(wrapAtLength(fmt.Sprintf(
"Vault does not store the generated master key. Without at least %d "+ "Vault does not store the generated root key. Without at least %d "+
"keys to reconstruct the master key, Vault will remain permanently "+ "keys to reconstruct the root key, Vault will remain permanently "+
"sealed!", "sealed!",
req.SecretThreshold))) req.SecretThreshold)))

View File

@ -51,7 +51,7 @@ Usage: vault operator rekey [options] [KEY]
Generates a new set of unseal keys. This can optionally change the total Generates a new set of unseal keys. This can optionally change the total
number of key shares or the required threshold of those key shares to number of key shares or the required threshold of those key shares to
reconstruct the master key. This operation is zero downtime, but it requires reconstruct the root key. This operation is zero downtime, but it requires
the Vault is unsealed and a quorum of existing unseal keys are provided. the Vault is unsealed and a quorum of existing unseal keys are provided.
An unseal key may be provided directly on the command line as an argument to An unseal key may be provided directly on the command line as an argument to
@ -129,7 +129,7 @@ func (c *OperatorRekeyCommand) Flags() *FlagSets {
Target: &c.flagKeyShares, Target: &c.flagKeyShares,
Default: 5, Default: 5,
Completion: complete.PredictAnything, Completion: complete.PredictAnything,
Usage: "Number of key shares to split the generated master key into. " + Usage: "Number of key shares to split the generated root key into. " +
"This is the number of \"unseal keys\" to generate.", "This is the number of \"unseal keys\" to generate.",
}) })
@ -139,7 +139,7 @@ func (c *OperatorRekeyCommand) Flags() *FlagSets {
Target: &c.flagKeyThreshold, Target: &c.flagKeyThreshold,
Default: 3, Default: 3,
Completion: complete.PredictAnything, Completion: complete.PredictAnything,
Usage: "Number of key shares required to reconstruct the master key. " + Usage: "Number of key shares required to reconstruct the root key. " +
"This must be less than or equal to -key-shares.", "This must be less than or equal to -key-shares.",
}) })

View File

@ -27,11 +27,11 @@ Usage: vault operator seal [options]
Seals the Vault server. Sealing tells the Vault server to stop responding Seals the Vault server. Sealing tells the Vault server to stop responding
to any operations until it is unsealed. When sealed, the Vault server to any operations until it is unsealed. When sealed, the Vault server
discards its in-memory master key to unlock the data, so it is physically discards its in-memory root key to unlock the data, so it is physically
blocked from responding to operations unsealed. blocked from responding to operations unsealed.
If an unseal is in progress, sealing the Vault will reset the unsealing If an unseal is in progress, sealing the Vault will reset the unsealing
process. Users will have to re-enter their portions of the master key again. process. Users will have to re-enter their portions of the root key again.
This command does nothing if the Vault server is already sealed. This command does nothing if the Vault server is already sealed.

View File

@ -34,9 +34,9 @@ func (c *OperatorUnsealCommand) Help() string {
helpText := ` helpText := `
Usage: vault operator unseal [options] [KEY] Usage: vault operator unseal [options] [KEY]
Provide a portion of the master key to unseal a Vault server. Vault starts Provide a portion of the root key to unseal a Vault server. Vault starts
in a sealed state. It cannot perform operations until it is unsealed. This in a sealed state. It cannot perform operations until it is unsealed. This
command accepts a portion of the master key (an "unseal key"). command accepts a portion of the root key (an "unseal key").
The unseal key can be supplied as an argument to the command, but this is The unseal key can be supplied as an argument to the command, but this is
not recommended as the unseal key will be available in your history: not recommended as the unseal key will be available in your history:

View File

@ -1144,7 +1144,7 @@ func (b *RaftBackend) SnapshotHTTP(out *logical.HTTPResponseWriter, access *seal
// Snapshot takes a raft snapshot, packages it into a archive file and writes it // Snapshot takes a raft snapshot, packages it into a archive file and writes it
// to the provided writer. Seal access is used to encrypt the SHASUM file so we // to the provided writer. Seal access is used to encrypt the SHASUM file so we
// can validate the snapshot was taken using the same master keys or not. // can validate the snapshot was taken using the same root keys or not.
func (b *RaftBackend) Snapshot(out io.Writer, access *seal.Access) error { func (b *RaftBackend) Snapshot(out io.Writer, access *seal.Access) error {
b.l.RLock() b.l.RLock()
defer b.l.RUnlock() defer b.l.RUnlock()
@ -1167,7 +1167,7 @@ func (b *RaftBackend) Snapshot(out io.Writer, access *seal.Access) error {
// WriteSnapshotToTemp reads a snapshot archive off the provided reader, // WriteSnapshotToTemp reads a snapshot archive off the provided reader,
// extracts the data and writes the snapshot to a temporary file. The seal // extracts the data and writes the snapshot to a temporary file. The seal
// access is used to decrypt the SHASUM file in the archive to ensure this // access is used to decrypt the SHASUM file in the archive to ensure this
// snapshot has the same master key as the running instance. If the provided // snapshot has the same root key as the running instance. If the provided
// access is nil then it will skip that validation. // access is nil then it will skip that validation.
func (b *RaftBackend) WriteSnapshotToTemp(in io.ReadCloser, access *seal.Access) (*os.File, func(), raft.SnapshotMeta, error) { func (b *RaftBackend) WriteSnapshotToTemp(in io.ReadCloser, access *seal.Access) (*os.File, func(), raft.SnapshotMeta, error) {
b.l.RLock() b.l.RLock()

View File

@ -35,15 +35,15 @@ const (
barrierInitPath = "barrier/init" barrierInitPath = "barrier/init"
// keyringPath is the location of the keyring data. This is encrypted // keyringPath is the location of the keyring data. This is encrypted
// by the master key. // by the root key.
keyringPath = "core/keyring" keyringPath = "core/keyring"
keyringPrefix = "core/" keyringPrefix = "core/"
// keyringUpgradePrefix is the path used to store keyring update entries. // keyringUpgradePrefix is the path used to store keyring update entries.
// When running in HA mode, the active instance will install the new key // When running in HA mode, the active instance will install the new key
// and re-write the keyring. For standby instances, they need an upgrade // and re-write the keyring. For standby instances, they need an upgrade
// path from key N to N+1. They cannot just use the master key because // path from key N to N+1. They cannot just use the root key because
// in the event of a rekey, that master key can no longer decrypt the keyring. // in the event of a rekey, that root key can no longer decrypt the keyring.
// When key N+1 is installed, we create an entry at "prefix/N" which uses // When key N+1 is installed, we create an entry at "prefix/N" which uses
// encryption key N to provide the N+1 key. The standby instances scan // encryption key N to provide the N+1 key. The standby instances scan
// for this periodically and refresh their keyring. The upgrade keys // for this periodically and refresh their keyring. The upgrade keys
@ -51,17 +51,17 @@ const (
// standby instances to upgrade without causing any disruption. // standby instances to upgrade without causing any disruption.
keyringUpgradePrefix = "core/upgrade/" keyringUpgradePrefix = "core/upgrade/"
// masterKeyPath is the location of the master key. This is encrypted // rootKeyPath is the location of the root key. This is encrypted
// by the latest key in the keyring. This is only used by standby instances // by the latest key in the keyring. This is only used by standby instances
// to handle the case of a rekey. If the active instance does a rekey, // to handle the case of a rekey. If the active instance does a rekey,
// the standby instances can no longer reload the keyring since they // the standby instances can no longer reload the keyring since they
// have the old master key. This key can be decrypted if you have the // have the old root key. This key can be decrypted if you have the
// keyring to discover the new master key. The new master key is then // keyring to discover the new root key. The new root key is then
// used to reload the keyring itself. // used to reload the keyring itself.
masterKeyPath = "core/master" rootKeyPath = "core/master"
// shamirKekPath is used with Shamir in v1.3+ to store a copy of the // shamirKekPath is used with Shamir in v1.3+ to store a copy of the
// unseal key behind the barrier. As with masterKeyPath this is primarily // unseal key behind the barrier. As with rootKeyPath this is primarily
// used by standbys to handle rekeys. It also comes into play when restoring // used by standbys to handle rekeys. It also comes into play when restoring
// raft snapshots. // raft snapshots.
shamirKekPath = "core/shamir-kek" shamirKekPath = "core/shamir-kek"
@ -75,14 +75,14 @@ const (
// a Vault. The barrier should only be Unlockable given its key. // a Vault. The barrier should only be Unlockable given its key.
type SecurityBarrier interface { type SecurityBarrier interface {
// Initialized checks if the barrier has been initialized // Initialized checks if the barrier has been initialized
// and has a master key set. // and has a root key set.
Initialized(ctx context.Context) (bool, error) Initialized(ctx context.Context) (bool, error)
// Initialize works only if the barrier has not been initialized // Initialize works only if the barrier has not been initialized
// and makes use of the given master key. When sealKey is provided // and makes use of the given root key. When sealKey is provided
// it's because we're using a new-style Shamir seal, and masterKey // it's because we're using a new-style Shamir seal, and rootKey
// is to be stored using sealKey to encrypt it. // is to be stored using sealKey to encrypt it.
Initialize(ctx context.Context, masterKey []byte, sealKey []byte, random io.Reader) error Initialize(ctx context.Context, rootKey []byte, sealKey []byte, random io.Reader) error
// GenerateKey is used to generate a new key // GenerateKey is used to generate a new key
GenerateKey(io.Reader) ([]byte, error) GenerateKey(io.Reader) ([]byte, error)
@ -94,27 +94,27 @@ type SecurityBarrier interface {
// is not expected to be able to perform any CRUD until it is unsealed. // is not expected to be able to perform any CRUD until it is unsealed.
Sealed() (bool, error) Sealed() (bool, error)
// Unseal is used to provide the master key which permits the barrier // Unseal is used to provide the unseal key which permits the barrier
// to be unsealed. If the key is not correct, the barrier remains sealed. // to be unsealed. If the key is not correct, the barrier remains sealed.
Unseal(ctx context.Context, key []byte) error Unseal(ctx context.Context, key []byte) error
// VerifyMaster is used to check if the given key matches the master key // VerifyRoot is used to check if the given key matches the root key
VerifyMaster(key []byte) error VerifyRoot(key []byte) error
// SetMasterKey is used to directly set a new master key. This is used in // SetRootKey is used to directly set a new root key. This is used in
// replicated scenarios due to the chicken and egg problem of reloading the // replicated scenarios due to the chicken and egg problem of reloading the
// keyring from disk before we have the master key to decrypt it. // keyring from disk before we have the root key to decrypt it.
SetMasterKey(key []byte) error SetRootKey(key []byte) error
// ReloadKeyring is used to re-read the underlying keyring. // ReloadKeyring is used to re-read the underlying keyring.
// This is used for HA deployments to ensure the latest keyring // This is used for HA deployments to ensure the latest keyring
// is present in the leader. // is present in the leader.
ReloadKeyring(ctx context.Context) error ReloadKeyring(ctx context.Context) error
// ReloadMasterKey is used to re-read the underlying masterkey. // ReloadRootKey is used to re-read the underlying root key.
// This is used for HA deployments to ensure the latest master key // This is used for HA deployments to ensure the latest root key
// is available for keyring reloading. // is available for keyring reloading.
ReloadMasterKey(ctx context.Context) error ReloadRootKey(ctx context.Context) error
// Seal is used to re-seal the barrier. This requires the barrier to // Seal is used to re-seal the barrier. This requires the barrier to
// be unsealed again to perform any further operations. // be unsealed again to perform any further operations.

View File

@ -122,7 +122,7 @@ func NewAESGCMBarrier(physical physical.Backend) (*AESGCMBarrier, error) {
} }
// Initialized checks if the barrier has been initialized // Initialized checks if the barrier has been initialized
// and has a master key set. // and has a root key set.
func (b *AESGCMBarrier) Initialized(ctx context.Context) (bool, error) { func (b *AESGCMBarrier) Initialized(ctx context.Context) (bool, error) {
if b.initialized.Load() { if b.initialized.Load() {
return true, nil return true, nil
@ -148,7 +148,7 @@ func (b *AESGCMBarrier) Initialized(ctx context.Context) (bool, error) {
} }
// Initialize works only if the barrier has not been initialized // Initialize works only if the barrier has not been initialized
// and makes use of the given master key. // and makes use of the given root key.
func (b *AESGCMBarrier) Initialize(ctx context.Context, key, sealKey []byte, reader io.Reader) error { func (b *AESGCMBarrier) Initialize(ctx context.Context, key, sealKey []byte, reader io.Reader) error {
// Verify the key size // Verify the key size
min, max := b.KeyLength() min, max := b.KeyLength()
@ -171,7 +171,7 @@ func (b *AESGCMBarrier) Initialize(ctx context.Context, key, sealKey []byte, rea
// Create a new keyring, install the keys // Create a new keyring, install the keys
keyring := NewKeyring() keyring := NewKeyring()
keyring = keyring.SetMasterKey(key) keyring = keyring.SetRootKey(key)
keyring, err = keyring.AddKey(&Key{ keyring, err = keyring.AddKey(&Key{
Term: 1, Term: 1,
Version: 1, Version: 1,
@ -205,7 +205,7 @@ func (b *AESGCMBarrier) Initialize(ctx context.Context, key, sealKey []byte, rea
} }
// persistKeyring is used to write out the keyring using the // persistKeyring is used to write out the keyring using the
// master key to encrypt it. // root key to encrypt it.
func (b *AESGCMBarrier) persistKeyring(ctx context.Context, keyring *Keyring) error { func (b *AESGCMBarrier) persistKeyring(ctx context.Context, keyring *Keyring) error {
// Create the keyring entry // Create the keyring entry
keyringBuf, err := keyring.Serialize() keyringBuf, err := keyring.Serialize()
@ -215,7 +215,7 @@ func (b *AESGCMBarrier) persistKeyring(ctx context.Context, keyring *Keyring) er
} }
// Create the AES-GCM // Create the AES-GCM
gcm, err := b.aeadFromKey(keyring.MasterKey()) gcm, err := b.aeadFromKey(keyring.RootKey())
if err != nil { if err != nil {
return err return err
} }
@ -235,36 +235,36 @@ func (b *AESGCMBarrier) persistKeyring(ctx context.Context, keyring *Keyring) er
return fmt.Errorf("failed to persist keyring: %w", err) return fmt.Errorf("failed to persist keyring: %w", err)
} }
// Serialize the master key value // Serialize the root key value
key := &Key{ key := &Key{
Term: 1, Term: 1,
Version: 1, Version: 1,
Value: keyring.MasterKey(), Value: keyring.RootKey(),
} }
keyBuf, err := key.Serialize() keyBuf, err := key.Serialize()
defer memzero(keyBuf) defer memzero(keyBuf)
if err != nil { if err != nil {
return fmt.Errorf("failed to serialize master key: %w", err) return fmt.Errorf("failed to serialize root key: %w", err)
} }
// Encrypt the master key // Encrypt the root key
activeKey := keyring.ActiveKey() activeKey := keyring.ActiveKey()
aead, err := b.aeadFromKey(activeKey.Value) aead, err := b.aeadFromKey(activeKey.Value)
if err != nil { if err != nil {
return err return err
} }
value, err = b.encryptTracked(masterKeyPath, activeKey.Term, aead, keyBuf) value, err = b.encryptTracked(rootKeyPath, activeKey.Term, aead, keyBuf)
if err != nil { if err != nil {
return err return err
} }
// Update the masterKeyPath for standby instances // Update the rootKeyPath for standby instances
pe = &physical.Entry{ pe = &physical.Entry{
Key: masterKeyPath, Key: rootKeyPath,
Value: value, Value: value,
} }
if err := b.backend.Put(ctx, pe); err != nil { if err := b.backend.Put(ctx, pe); err != nil {
return fmt.Errorf("failed to persist master key: %w", err) return fmt.Errorf("failed to persist root key: %w", err)
} }
return nil return nil
} }
@ -292,14 +292,14 @@ func (b *AESGCMBarrier) Sealed() (bool, error) {
return sealed, nil return sealed, nil
} }
// VerifyMaster is used to check if the given key matches the master key // VerifyRoot is used to check if the given key matches the root key
func (b *AESGCMBarrier) VerifyMaster(key []byte) error { func (b *AESGCMBarrier) VerifyRoot(key []byte) error {
b.l.RLock() b.l.RLock()
defer b.l.RUnlock() defer b.l.RUnlock()
if b.sealed { if b.sealed {
return ErrBarrierSealed return ErrBarrierSealed
} }
if subtle.ConstantTimeCompare(key, b.keyring.MasterKey()) != 1 { if subtle.ConstantTimeCompare(key, b.keyring.RootKey()) != 1 {
return ErrBarrierInvalidKey return ErrBarrierInvalidKey
} }
return nil return nil
@ -313,7 +313,7 @@ func (b *AESGCMBarrier) ReloadKeyring(ctx context.Context) error {
defer b.l.Unlock() defer b.l.Unlock()
// Create the AES-GCM // Create the AES-GCM
gcm, err := b.aeadFromKey(b.keyring.MasterKey()) gcm, err := b.aeadFromKey(b.keyring.RootKey())
if err != nil { if err != nil {
return err return err
} }
@ -367,19 +367,19 @@ func (b *AESGCMBarrier) recoverKeyring(plaintext []byte) error {
return nil return nil
} }
// ReloadMasterKey is used to re-read the underlying masterkey. // ReloadRootKey is used to re-read the underlying root key.
// This is used for HA deployments to ensure the latest master key // This is used for HA deployments to ensure the latest root key
// is available for keyring reloading. // is available for keyring reloading.
func (b *AESGCMBarrier) ReloadMasterKey(ctx context.Context) error { func (b *AESGCMBarrier) ReloadRootKey(ctx context.Context) error {
// Read the masterKeyPath upgrade // Read the rootKeyPath upgrade
out, err := b.Get(ctx, masterKeyPath) out, err := b.Get(ctx, rootKeyPath)
if err != nil { if err != nil {
return fmt.Errorf("failed to read master key path: %w", err) return fmt.Errorf("failed to read root key path: %w", err)
} }
// The masterKeyPath could be missing (backwards incompatible), // The rootKeyPath could be missing (backwards incompatible),
// we can ignore this and attempt to make progress with the current // we can ignore this and attempt to make progress with the current
// master key. // root key.
if out == nil { if out == nil {
return nil return nil
} }
@ -388,35 +388,35 @@ func (b *AESGCMBarrier) ReloadMasterKey(ctx context.Context) error {
b.l.Lock() b.l.Lock()
defer b.l.Unlock() defer b.l.Unlock()
out, err = b.lockSwitchedGet(ctx, masterKeyPath, false) out, err = b.lockSwitchedGet(ctx, rootKeyPath, false)
if err != nil { if err != nil {
return fmt.Errorf("failed to read master key path: %w", err) return fmt.Errorf("failed to read root key path: %w", err)
} }
if out == nil { if out == nil {
return nil return nil
} }
// Deserialize the master key // Deserialize the root key
key, err := DeserializeKey(out.Value) key, err := DeserializeKey(out.Value)
memzero(out.Value) memzero(out.Value)
if err != nil { if err != nil {
return fmt.Errorf("failed to deserialize key: %w", err) return fmt.Errorf("failed to deserialize key: %w", err)
} }
// Check if the master key is the same // Check if the root key is the same
if subtle.ConstantTimeCompare(b.keyring.MasterKey(), key.Value) == 1 { if subtle.ConstantTimeCompare(b.keyring.RootKey(), key.Value) == 1 {
return nil return nil
} }
// Update the master key // Update the root key
oldKeyring := b.keyring oldKeyring := b.keyring
b.keyring = b.keyring.SetMasterKey(key.Value) b.keyring = b.keyring.SetRootKey(key.Value)
oldKeyring.Zeroize(false) oldKeyring.Zeroize(false)
return nil return nil
} }
// Unseal is used to provide the master key which permits the barrier // Unseal is used to provide the root key which permits the barrier
// to be unsealed. If the key is not correct, the barrier remains sealed. // to be unsealed. If the key is not correct, the barrier remains sealed.
func (b *AESGCMBarrier) Unseal(ctx context.Context, key []byte) error { func (b *AESGCMBarrier) Unseal(ctx context.Context, key []byte) error {
b.l.Lock() b.l.Lock()
@ -499,9 +499,9 @@ func (b *AESGCMBarrier) Unseal(ctx context.Context, key []byte) error {
// Setup a new keyring, this is for backwards compatibility // Setup a new keyring, this is for backwards compatibility
keyringNew := NewKeyring() keyringNew := NewKeyring()
keyring := keyringNew.SetMasterKey(key) keyring := keyringNew.SetRootKey(key)
// AddKey reuses the master, so we are only zeroizing after this call // AddKey reuses the root, so we are only zeroizing after this call
defer keyringNew.Zeroize(false) defer keyringNew.Zeroize(false)
keyring, err = keyring.AddKey(&Key{ keyring, err = keyring.AddKey(&Key{
@ -719,12 +719,12 @@ func (b *AESGCMBarrier) ActiveKeyInfo() (*KeyInfo, error) {
return info, nil return info, nil
} }
// Rekey is used to change the master key used to protect the keyring // Rekey is used to change the root key used to protect the keyring
func (b *AESGCMBarrier) Rekey(ctx context.Context, key []byte) error { func (b *AESGCMBarrier) Rekey(ctx context.Context, key []byte) error {
b.l.Lock() b.l.Lock()
defer b.l.Unlock() defer b.l.Unlock()
newKeyring, err := b.updateMasterKeyCommon(key) newKeyring, err := b.updateRootKeyCommon(key)
if err != nil { if err != nil {
return err return err
} }
@ -741,13 +741,13 @@ func (b *AESGCMBarrier) Rekey(ctx context.Context, key []byte) error {
return nil return nil
} }
// SetMasterKey updates the keyring's in-memory master key but does not persist // SetRootKey updates the keyring's in-memory root key but does not persist
// anything to storage // anything to storage
func (b *AESGCMBarrier) SetMasterKey(key []byte) error { func (b *AESGCMBarrier) SetRootKey(key []byte) error {
b.l.Lock() b.l.Lock()
defer b.l.Unlock() defer b.l.Unlock()
newKeyring, err := b.updateMasterKeyCommon(key) newKeyring, err := b.updateRootKeyCommon(key)
if err != nil { if err != nil {
return err return err
} }
@ -759,9 +759,9 @@ func (b *AESGCMBarrier) SetMasterKey(key []byte) error {
return nil return nil
} }
// Performs common tasks related to updating the master key; note that the lock // Performs common tasks related to updating the root key; note that the lock
// must be held before calling this function // must be held before calling this function
func (b *AESGCMBarrier) updateMasterKeyCommon(key []byte) (*Keyring, error) { func (b *AESGCMBarrier) updateRootKeyCommon(key []byte) (*Keyring, error) {
if b.sealed { if b.sealed {
return nil, ErrBarrierSealed return nil, ErrBarrierSealed
} }
@ -772,7 +772,7 @@ func (b *AESGCMBarrier) updateMasterKeyCommon(key []byte) (*Keyring, error) {
return nil, fmt.Errorf("key size must be %d or %d", min, max) return nil, fmt.Errorf("key size must be %d or %d", min, max)
} }
return b.keyring.SetMasterKey(key), nil return b.keyring.SetRootKey(key), nil
} }
// Put is used to insert or update an entry // Put is used to insert or update an entry

View File

@ -245,8 +245,8 @@ func testInitAndUnseal(t *testing.T, b SecurityBarrier) (error, *logical.Storage
t.Fatalf("should be unsealed") t.Fatalf("should be unsealed")
} }
// Verify the master key // Verify the root key
if err := b.VerifyMaster(key); err != nil { if err := b.VerifyRoot(key); err != nil {
t.Fatalf("err: %v", err) t.Fatalf("err: %v", err)
} }
return err, e, key return err, e, key
@ -374,7 +374,7 @@ func testBarrier_Rekey(t *testing.T, b SecurityBarrier) {
} }
// Verify the master key // Verify the master key
if err := b.VerifyMaster(key); err != nil { if err := b.VerifyRoot(key); err != nil {
t.Fatalf("err: %v", err) t.Fatalf("err: %v", err)
} }
@ -386,12 +386,12 @@ func testBarrier_Rekey(t *testing.T, b SecurityBarrier) {
} }
// Verify the old master key // Verify the old master key
if err := b.VerifyMaster(key); err != ErrBarrierInvalidKey { if err := b.VerifyRoot(key); err != ErrBarrierInvalidKey {
t.Fatalf("err: %v", err) t.Fatalf("err: %v", err)
} }
// Verify the new master key // Verify the new master key
if err := b.VerifyMaster(newKey); err != nil { if err := b.VerifyRoot(newKey); err != nil {
t.Fatalf("err: %v", err) t.Fatalf("err: %v", err)
} }
@ -530,7 +530,7 @@ func testBarrier_Upgrade_Rekey(t *testing.T, b1, b2 SecurityBarrier) {
} }
// Reload the master key // Reload the master key
err = b2.ReloadMasterKey(context.Background()) err = b2.ReloadRootKey(context.Background())
if err != nil { if err != nil {
t.Fatalf("err: %v", err) t.Fatalf("err: %v", err)
} }

View File

@ -2547,7 +2547,7 @@ func (c *Core) adjustSealConfigDuringMigration(existBarrierSealConfig, existReco
} }
} }
func (c *Core) unsealKeyToMasterKeyPostUnseal(ctx context.Context, combinedKey []byte) ([]byte, error) { func (c *Core) unsealKeyToRootKeyPostUnseal(ctx context.Context, combinedKey []byte) ([]byte, error) {
return c.unsealKeyToMasterKey(ctx, c.seal, combinedKey, true, false) return c.unsealKeyToMasterKey(ctx, c.seal, combinedKey, true, false)
} }
@ -2586,7 +2586,7 @@ func (c *Core) unsealKeyToMasterKey(ctx context.Context, seal Seal, combinedKey
} }
return storedKeys[0], nil return storedKeys[0], nil
case vaultseal.StoredKeysSupportedShamirMaster: case vaultseal.StoredKeysSupportedShamirRoot:
if useTestSeal { if useTestSeal {
testseal := NewDefaultSeal(&vaultseal.Access{ testseal := NewDefaultSeal(&vaultseal.Access{
Wrapper: aeadwrapper.NewShamirWrapper(&wrapping.WrapperOptions{ Wrapper: aeadwrapper.NewShamirWrapper(&wrapping.WrapperOptions{

View File

@ -38,12 +38,12 @@ type GenerateRootStrategy interface {
type generateStandardRootToken struct{} type generateStandardRootToken struct{}
func (g generateStandardRootToken) authenticate(ctx context.Context, c *Core, combinedKey []byte) error { func (g generateStandardRootToken) authenticate(ctx context.Context, c *Core, combinedKey []byte) error {
masterKey, err := c.unsealKeyToMasterKeyPostUnseal(ctx, combinedKey) rootKey, err := c.unsealKeyToRootKeyPostUnseal(ctx, combinedKey)
if err != nil { if err != nil {
return fmt.Errorf("unable to authenticate: %w", err) return fmt.Errorf("unable to authenticate: %w", err)
} }
if err := c.barrier.VerifyMaster(masterKey); err != nil { if err := c.barrier.VerifyRoot(rootKey); err != nil {
return fmt.Errorf("master key verification failed: %w", err) return fmt.Errorf("root key verification failed: %w", err)
} }
return nil return nil
@ -303,7 +303,7 @@ func (c *Core) GenerateRootUpdate(ctx context.Context, key []byte, nonce string,
combinedKey, err = shamir.Combine(c.generateRootProgress) combinedKey, err = shamir.Combine(c.generateRootProgress)
c.generateRootProgress = nil c.generateRootProgress = nil
if err != nil { if err != nil {
return nil, fmt.Errorf("failed to compute master key: %w", err) return nil, fmt.Errorf("failed to compute root key: %w", err)
} }
} }

View File

@ -21,12 +21,12 @@ type generateRecoveryToken struct {
} }
func (g *generateRecoveryToken) authenticate(ctx context.Context, c *Core, combinedKey []byte) error { func (g *generateRecoveryToken) authenticate(ctx context.Context, c *Core, combinedKey []byte) error {
key, err := c.unsealKeyToMasterKeyPostUnseal(ctx, combinedKey) key, err := c.unsealKeyToRootKeyPostUnseal(ctx, combinedKey)
if err != nil { if err != nil {
return fmt.Errorf("unable to authenticate: %w", err) return fmt.Errorf("unable to authenticate: %w", err)
} }
// Use the retrieved master key to unseal the barrier // Use the retrieved root key to unseal the barrier
if err := c.barrier.Unseal(ctx, key); err != nil { if err := c.barrier.Unseal(ctx, key); err != nil {
return fmt.Errorf("recovery operation token generation failed, cannot unseal barrier: %w", err) return fmt.Errorf("recovery operation token generation failed, cannot unseal barrier: %w", err)
} }

View File

@ -825,9 +825,9 @@ func (c *Core) checkKeyUpgrades(ctx context.Context) error {
return nil return nil
} }
func (c *Core) reloadMasterKey(ctx context.Context) error { func (c *Core) reloadRootKey(ctx context.Context) error {
if err := c.barrier.ReloadMasterKey(ctx); err != nil { if err := c.barrier.ReloadRootKey(ctx); err != nil {
return fmt.Errorf("error reloading master key: %w", err) return fmt.Errorf("error reloading root key: %w", err)
} }
return nil return nil
} }
@ -841,7 +841,7 @@ func (c *Core) reloadShamirKey(ctx context.Context) error {
switch c.seal.StoredKeysSupported() { switch c.seal.StoredKeysSupported() {
case seal.StoredKeysSupportedGeneric: case seal.StoredKeysSupportedGeneric:
return nil return nil
case seal.StoredKeysSupportedShamirMaster: case seal.StoredKeysSupportedShamirRoot:
entry, err := c.barrier.Get(ctx, shamirKekPath) entry, err := c.barrier.Get(ctx, shamirKekPath)
if err != nil { if err != nil {
return err return err
@ -855,7 +855,7 @@ func (c *Core) reloadShamirKey(ctx context.Context) error {
if err != nil { if err != nil {
return fmt.Errorf("failed to update seal access: %w", err) return fmt.Errorf("failed to update seal access: %w", err)
} }
shamirKey = keyring.masterKey shamirKey = keyring.rootKey
} }
return c.seal.GetAccess().Wrapper.(*aeadwrapper.ShamirWrapper).SetAESGCMKeyBytes(shamirKey) return c.seal.GetAccess().Wrapper.(*aeadwrapper.ShamirWrapper).SetAESGCMKeyBytes(shamirKey)
} }
@ -865,8 +865,8 @@ func (c *Core) performKeyUpgrades(ctx context.Context) error {
return fmt.Errorf("error checking for key upgrades: %w", err) return fmt.Errorf("error checking for key upgrades: %w", err)
} }
if err := c.reloadMasterKey(ctx); err != nil { if err := c.reloadRootKey(ctx); err != nil {
return fmt.Errorf("error reloading master key: %w", err) return fmt.Errorf("error reloading root key: %w", err)
} }
if err := c.barrier.ReloadKeyring(ctx); err != nil { if err := c.barrier.ReloadKeyring(ctx); err != nil {

View File

@ -122,19 +122,19 @@ func (c *Core) InitializedLocally(ctx context.Context) (bool, error) {
} }
func (c *Core) generateShares(sc *SealConfig) ([]byte, [][]byte, error) { func (c *Core) generateShares(sc *SealConfig) ([]byte, [][]byte, error) {
// Generate a master key // Generate a root key
masterKey, err := c.barrier.GenerateKey(c.secureRandomReader) rootKey, err := c.barrier.GenerateKey(c.secureRandomReader)
if err != nil { if err != nil {
return nil, nil, fmt.Errorf("key generation failed: %w", err) return nil, nil, fmt.Errorf("key generation failed: %w", err)
} }
// Return the master key if only a single key part is used // Return the root key if only a single key part is used
var unsealKeys [][]byte var unsealKeys [][]byte
if sc.SecretShares == 1 { if sc.SecretShares == 1 {
unsealKeys = append(unsealKeys, masterKey) unsealKeys = append(unsealKeys, rootKey)
} else { } else {
// Split the master key using the Shamir algorithm // Split the root key using the Shamir algorithm
shares, err := shamir.Split(masterKey, sc.SecretShares, sc.SecretThreshold) shares, err := shamir.Split(rootKey, sc.SecretShares, sc.SecretThreshold)
if err != nil { if err != nil {
return nil, nil, fmt.Errorf("failed to generate barrier shares: %w", err) return nil, nil, fmt.Errorf("failed to generate barrier shares: %w", err)
} }
@ -154,7 +154,7 @@ func (c *Core) generateShares(sc *SealConfig) ([]byte, [][]byte, error) {
unsealKeys = encryptedShares unsealKeys = encryptedShares
} }
return masterKey, unsealKeys, nil return rootKey, unsealKeys, nil
} }
// Initialize is used to initialize the Vault with the given // Initialize is used to initialize the Vault with the given
@ -172,7 +172,7 @@ func (c *Core) Initialize(ctx context.Context, initParams *InitParams) (*InitRes
// N.B. Although the core is capable of handling situations where some keys // N.B. Although the core is capable of handling situations where some keys
// are stored and some aren't, in practice, replication + HSMs makes this // are stored and some aren't, in practice, replication + HSMs makes this
// extremely hard to reason about, to the point that it will probably never // extremely hard to reason about, to the point that it will probably never
// be supported. The reason is that each HSM needs to encode the master key // be supported. The reason is that each HSM needs to encode the root key
// separately, which means the shares must be generated independently, // separately, which means the shares must be generated independently,
// which means both that the shares will be different *AND* there would // which means both that the shares will be different *AND* there would
// need to be a way to actually allow fetching of the generated keys by // need to be a way to actually allow fetching of the generated keys by
@ -322,7 +322,7 @@ func (c *Core) Initialize(ctx context.Context, initParams *InitParams) (*InitRes
// If we are storing shares, pop them out of the returned results and push // If we are storing shares, pop them out of the returned results and push
// them through the seal // them through the seal
switch c.seal.StoredKeysSupported() { switch c.seal.StoredKeysSupported() {
case seal.StoredKeysSupportedShamirMaster: case seal.StoredKeysSupportedShamirRoot:
keysToStore := [][]byte{barrierKey} keysToStore := [][]byte{barrierKey}
if err := c.seal.GetAccess().Wrapper.(*aeadwrapper.ShamirWrapper).SetAESGCMKeyBytes(sealKey); err != nil { if err := c.seal.GetAccess().Wrapper.(*aeadwrapper.ShamirWrapper).SetAESGCMKeyBytes(sealKey); err != nil {
c.logger.Error("failed to set seal key", "error", err) c.logger.Error("failed to set seal key", "error", err)

View File

@ -31,11 +31,11 @@ var (
// The term used to encrypt a key is prefixed to the key written out. // The term used to encrypt a key is prefixed to the key written out.
// All data is encrypted with the latest key, but storing the old keys // All data is encrypted with the latest key, but storing the old keys
// allows for decryption of keys written previously. Along with the encryption // allows for decryption of keys written previously. Along with the encryption
// keys, the keyring also tracks the master key. This is necessary so that // keys, the keyring also tracks the root key. This is necessary so that
// when a new key is added to the keyring, we can encrypt with the master key // when a new key is added to the keyring, we can encrypt with the root key
// and write out the new keyring. // and write out the new keyring.
type Keyring struct { type Keyring struct {
masterKey []byte rootKey []byte
keys map[uint32]*Key keys map[uint32]*Key
activeTerm uint32 activeTerm uint32
rotationConfig KeyRotationConfig rotationConfig KeyRotationConfig
@ -90,7 +90,7 @@ func NewKeyring() *Keyring {
// Clone returns a new copy of the keyring // Clone returns a new copy of the keyring
func (k *Keyring) Clone() *Keyring { func (k *Keyring) Clone() *Keyring {
clone := &Keyring{ clone := &Keyring{
masterKey: k.masterKey, rootKey: k.rootKey,
keys: make(map[uint32]*Key, len(k.keys)), keys: make(map[uint32]*Key, len(k.keys)),
activeTerm: k.activeTerm, activeTerm: k.activeTerm,
rotationConfig: k.rotationConfig, rotationConfig: k.rotationConfig,
@ -170,25 +170,25 @@ func (k *Keyring) TermKey(term uint32) *Key {
return k.keys[term] return k.keys[term]
} }
// SetMasterKey is used to update the master key // SetRootKey is used to update the root key
func (k *Keyring) SetMasterKey(val []byte) *Keyring { func (k *Keyring) SetRootKey(val []byte) *Keyring {
valCopy := make([]byte, len(val)) valCopy := make([]byte, len(val))
copy(valCopy, val) copy(valCopy, val)
clone := k.Clone() clone := k.Clone()
clone.masterKey = valCopy clone.rootKey = valCopy
return clone return clone
} }
// MasterKey returns the master key // RootKey returns the root key
func (k *Keyring) MasterKey() []byte { func (k *Keyring) RootKey() []byte {
return k.masterKey return k.rootKey
} }
// Serialize is used to create a byte encoded keyring // Serialize is used to create a byte encoded keyring
func (k *Keyring) Serialize() ([]byte, error) { func (k *Keyring) Serialize() ([]byte, error) {
// Create the encoded entry // Create the encoded entry
enc := EncodedKeyring{ enc := EncodedKeyring{
MasterKey: k.masterKey, MasterKey: k.rootKey,
RotationConfig: k.rotationConfig, RotationConfig: k.rotationConfig,
} }
for _, key := range k.keys { for _, key := range k.keys {
@ -210,7 +210,7 @@ func DeserializeKeyring(buf []byte) (*Keyring, error) {
// Create a new keyring // Create a new keyring
k := NewKeyring() k := NewKeyring()
k.masterKey = enc.MasterKey k.rootKey = enc.MasterKey
k.rotationConfig = enc.RotationConfig k.rotationConfig = enc.RotationConfig
k.rotationConfig.Sanitize() k.rotationConfig.Sanitize()
for _, key := range enc.Keys { for _, key := range enc.Keys {
@ -229,8 +229,8 @@ func (k *Keyring) Zeroize(keysToo bool) {
if k == nil { if k == nil {
return return
} }
if k.masterKey != nil { if k.rootKey != nil {
memzero(k.masterKey) memzero(k.rootKey)
} }
if !keysToo || k.keys == nil { if !keysToo || k.keys == nil {
return return

View File

@ -113,21 +113,21 @@ func TestKeyring_MasterKey(t *testing.T) {
master2 := []byte("test2") master2 := []byte("test2")
// Check no master // Check no master
out := k.MasterKey() out := k.RootKey()
if out != nil { if out != nil {
t.Fatalf("bad: %v", out) t.Fatalf("bad: %v", out)
} }
// Set master // Set master
k = k.SetMasterKey(master) k = k.SetRootKey(master)
out = k.MasterKey() out = k.RootKey()
if !bytes.Equal(out, master) { if !bytes.Equal(out, master) {
t.Fatalf("bad: %v", out) t.Fatalf("bad: %v", out)
} }
// Update master // Update master
k = k.SetMasterKey(master2) k = k.SetRootKey(master2)
out = k.MasterKey() out = k.RootKey()
if !bytes.Equal(out, master2) { if !bytes.Equal(out, master2) {
t.Fatalf("bad: %v", out) t.Fatalf("bad: %v", out)
} }
@ -136,7 +136,7 @@ func TestKeyring_MasterKey(t *testing.T) {
func TestKeyring_Serialize(t *testing.T) { func TestKeyring_Serialize(t *testing.T) {
k := NewKeyring() k := NewKeyring()
master := []byte("test") master := []byte("test")
k = k.SetMasterKey(master) k = k.SetRootKey(master)
now := time.Now() now := time.Now()
testKey := []byte("testing") testKey := []byte("testing")
@ -154,7 +154,7 @@ func TestKeyring_Serialize(t *testing.T) {
t.Fatalf("err: %v", err) t.Fatalf("err: %v", err)
} }
out := k2.MasterKey() out := k2.RootKey()
if !bytes.Equal(out, master) { if !bytes.Equal(out, master) {
t.Fatalf("bad: %v", out) t.Fatalf("bad: %v", out)
} }

View File

@ -156,7 +156,7 @@ func (b *SystemBackend) configPaths() []*framework.Path {
Fields: map[string]*framework.FieldSchema{ Fields: map[string]*framework.FieldSchema{
"key": { "key": {
Type: framework.TypeString, Type: framework.TypeString,
Description: "Specifies a single master key share.", Description: "Specifies a single unseal key share.",
}, },
"nonce": { "nonce": {
Type: framework.TypeString, Type: framework.TypeString,
@ -165,8 +165,8 @@ func (b *SystemBackend) configPaths() []*framework.Path {
}, },
Operations: map[logical.Operation]framework.OperationHandler{ Operations: map[logical.Operation]framework.OperationHandler{
logical.UpdateOperation: &framework.PathOperation{ logical.UpdateOperation: &framework.PathOperation{
Summary: "Enter a single master key share to progress the root generation attempt.", Summary: "Enter a single unseal key share to progress the root generation attempt.",
Description: "If the threshold number of master key shares is reached, Vault will complete the root generation and issue the new token. Otherwise, this API must be called multiple times until that threshold is met. The attempt nonce must be provided with each call.", Description: "If the threshold number of unseal key shares is reached, Vault will complete the root generation and issue the new token. Otherwise, this API must be called multiple times until that threshold is met. The attempt nonce must be provided with each call.",
}, },
}, },
@ -239,11 +239,11 @@ func (b *SystemBackend) configPaths() []*framework.Path {
}, },
"secret_shares": { "secret_shares": {
Type: framework.TypeInt, Type: framework.TypeInt,
Description: "Specifies the number of shares to split the master key into.", Description: "Specifies the number of shares to split the unseal key into.",
}, },
"secret_threshold": { "secret_threshold": {
Type: framework.TypeInt, Type: framework.TypeInt,
Description: "Specifies the number of shares required to reconstruct the master key. This must be less than or equal secret_shares. If using Vault HSM with auto-unsealing, this value must be the same as `secret_shares`.", Description: "Specifies the number of shares required to reconstruct the unseal key. This must be less than or equal secret_shares. If using Vault HSM with auto-unsealing, this value must be the same as `secret_shares`.",
}, },
"stored_shares": { "stored_shares": {
Type: framework.TypeInt, Type: framework.TypeInt,
@ -299,11 +299,11 @@ func (b *SystemBackend) rekeyPaths() []*framework.Path {
Fields: map[string]*framework.FieldSchema{ Fields: map[string]*framework.FieldSchema{
"secret_shares": { "secret_shares": {
Type: framework.TypeInt, Type: framework.TypeInt,
Description: "Specifies the number of shares to split the master key into.", Description: "Specifies the number of shares to split the unseal key into.",
}, },
"secret_threshold": { "secret_threshold": {
Type: framework.TypeInt, Type: framework.TypeInt,
Description: "Specifies the number of shares required to reconstruct the master key. This must be less than or equal secret_shares. If using Vault HSM with auto-unsealing, this value must be the same as secret_shares.", Description: "Specifies the number of shares required to reconstruct the unseal key. This must be less than or equal secret_shares. If using Vault HSM with auto-unsealing, this value must be the same as secret_shares.",
}, },
"pgp_keys": { "pgp_keys": {
Type: framework.TypeCommaStringSlice, Type: framework.TypeCommaStringSlice,
@ -372,7 +372,7 @@ func (b *SystemBackend) rekeyPaths() []*framework.Path {
Fields: map[string]*framework.FieldSchema{ Fields: map[string]*framework.FieldSchema{
"key": { "key": {
Type: framework.TypeString, Type: framework.TypeString,
Description: "Specifies a single master key share.", Description: "Specifies a single unseal key share.",
}, },
"nonce": { "nonce": {
Type: framework.TypeString, Type: framework.TypeString,
@ -382,7 +382,7 @@ func (b *SystemBackend) rekeyPaths() []*framework.Path {
Operations: map[logical.Operation]framework.OperationHandler{ Operations: map[logical.Operation]framework.OperationHandler{
logical.UpdateOperation: &framework.PathOperation{ logical.UpdateOperation: &framework.PathOperation{
Summary: "Enter a single master key share to progress the rekey of the Vault.", Summary: "Enter a single unseal key share to progress the rekey of the Vault.",
}, },
}, },
}, },
@ -392,7 +392,7 @@ func (b *SystemBackend) rekeyPaths() []*framework.Path {
Fields: map[string]*framework.FieldSchema{ Fields: map[string]*framework.FieldSchema{
"key": { "key": {
Type: framework.TypeString, Type: framework.TypeString,
Description: "Specifies a single master share key from the new set of shares.", Description: "Specifies a single unseal share key from the new set of shares.",
}, },
"nonce": { "nonce": {
Type: framework.TypeString, Type: framework.TypeString,
@ -430,7 +430,7 @@ func (b *SystemBackend) rekeyPaths() []*framework.Path {
Fields: map[string]*framework.FieldSchema{ Fields: map[string]*framework.FieldSchema{
"key": { "key": {
Type: framework.TypeString, Type: framework.TypeString,
Description: "Specifies a single master key share. This is required unless reset is true.", Description: "Specifies a single unseal key share. This is required unless reset is true.",
}, },
"reset": { "reset": {
Type: framework.TypeBool, Type: framework.TypeBool,

View File

@ -605,7 +605,7 @@ func (c *Core) checkRaftTLSKeyUpgrades(ctx context.Context) error {
// handleSnapshotRestore is for the raft backend to hook back into core after a // handleSnapshotRestore is for the raft backend to hook back into core after a
// snapshot is restored so we can clear the necessary caches and handle changing // snapshot is restored so we can clear the necessary caches and handle changing
// keyrings or master keys // keyrings or root keys
func (c *Core) raftSnapshotRestoreCallback(grabLock bool, sealNode bool) func(context.Context) error { func (c *Core) raftSnapshotRestoreCallback(grabLock bool, sealNode bool) func(context.Context) error {
return func(ctx context.Context) (retErr error) { return func(ctx context.Context) (retErr error) {
c.logger.Info("running post snapshot restore invalidations") c.logger.Info("running post snapshot restore invalidations")
@ -635,10 +635,10 @@ func (c *Core) raftSnapshotRestoreCallback(grabLock bool, sealNode bool) func(co
c.physicalCache.Purge(ctx) c.physicalCache.Purge(ctx)
// Reload the keyring in case it changed. If this fails it's likely // Reload the keyring in case it changed. If this fails it's likely
// we've changed master keys. // we've changed root keys.
err := c.performKeyUpgrades(ctx) err := c.performKeyUpgrades(ctx)
if err != nil { if err != nil {
// The snapshot contained a master key or keyring we couldn't // The snapshot contained a root key or keyring we couldn't
// recover // recover
switch c.seal.BarrierType() { switch c.seal.BarrierType() {
case wrapping.Shamir: case wrapping.Shamir:
@ -667,7 +667,7 @@ func (c *Core) raftSnapshotRestoreCallback(grabLock bool, sealNode bool) func(co
c.logger.Error("raft snapshot restore failed to unseal barrier", "error", err) c.logger.Error("raft snapshot restore failed to unseal barrier", "error", err)
return err return err
} }
c.logger.Info("done reloading master key using auto seal") c.logger.Info("done reloading root key using auto seal")
} }
} }

View File

@ -331,7 +331,7 @@ func (c *Core) BarrierRekeyUpdate(ctx context.Context, key []byte, nonce string)
// Get the seal configuration // Get the seal configuration
var existingConfig *SealConfig var existingConfig *SealConfig
var err error var err error
var useRecovery bool // Determines whether recovery key is being used to rekey the master key var useRecovery bool // Determines whether recovery key is being used to rekey the root key
if c.seal.StoredKeysSupported() == seal.StoredKeysSupportedGeneric && c.seal.RecoveryKeySupported() { if c.seal.StoredKeysSupported() == seal.StoredKeysSupportedGeneric && c.seal.RecoveryKeySupported() {
existingConfig, err = c.seal.RecoveryConfig(ctx) existingConfig, err = c.seal.RecoveryConfig(ctx)
useRecovery = true useRecovery = true
@ -377,7 +377,7 @@ func (c *Core) BarrierRekeyUpdate(ctx context.Context, key []byte, nonce string)
return nil, nil return nil, nil
} }
// Recover the master key or recovery key // Recover the root key or recovery key
var recoveredKey []byte var recoveredKey []byte
if existingConfig.SecretThreshold == 1 { if existingConfig.SecretThreshold == 1 {
recoveredKey = c.barrierRekeyConfig.RekeyProgress[0] recoveredKey = c.barrierRekeyConfig.RekeyProgress[0]
@ -386,7 +386,7 @@ func (c *Core) BarrierRekeyUpdate(ctx context.Context, key []byte, nonce string)
recoveredKey, err = shamir.Combine(c.barrierRekeyConfig.RekeyProgress) recoveredKey, err = shamir.Combine(c.barrierRekeyConfig.RekeyProgress)
c.barrierRekeyConfig.RekeyProgress = nil c.barrierRekeyConfig.RekeyProgress = nil
if err != nil { if err != nil {
return nil, logical.CodedError(http.StatusInternalServerError, fmt.Errorf("failed to compute master key: %w", err).Error()) return nil, logical.CodedError(http.StatusInternalServerError, fmt.Errorf("failed to compute root key: %w", err).Error())
} }
} }
@ -397,7 +397,7 @@ func (c *Core) BarrierRekeyUpdate(ctx context.Context, key []byte, nonce string)
return nil, logical.CodedError(http.StatusBadRequest, fmt.Errorf("recovery key verification failed: %w", err).Error()) return nil, logical.CodedError(http.StatusBadRequest, fmt.Errorf("recovery key verification failed: %w", err).Error())
} }
case c.seal.BarrierType() == wrapping.Shamir: case c.seal.BarrierType() == wrapping.Shamir:
if c.seal.StoredKeysSupported() == seal.StoredKeysSupportedShamirMaster { if c.seal.StoredKeysSupported() == seal.StoredKeysSupportedShamirRoot {
testseal := NewDefaultSeal(&seal.Access{ testseal := NewDefaultSeal(&seal.Access{
Wrapper: aeadwrapper.NewShamirWrapper(&wrapping.WrapperOptions{ Wrapper: aeadwrapper.NewShamirWrapper(&wrapping.WrapperOptions{
Logger: c.logger.Named("testseal"), Logger: c.logger.Named("testseal"),
@ -415,23 +415,23 @@ func (c *Core) BarrierRekeyUpdate(ctx context.Context, key []byte, nonce string)
testseal.SetCachedBarrierConfig(cfg) testseal.SetCachedBarrierConfig(cfg)
stored, err := testseal.GetStoredKeys(ctx) stored, err := testseal.GetStoredKeys(ctx)
if err != nil { if err != nil {
return nil, logical.CodedError(http.StatusInternalServerError, fmt.Errorf("failed to read master key: %w", err).Error()) return nil, logical.CodedError(http.StatusInternalServerError, fmt.Errorf("failed to read root key: %w", err).Error())
} }
recoveredKey = stored[0] recoveredKey = stored[0]
} }
if err := c.barrier.VerifyMaster(recoveredKey); err != nil { if err := c.barrier.VerifyRoot(recoveredKey); err != nil {
c.logger.Error("master key verification failed", "error", err) c.logger.Error("root key verification failed", "error", err)
return nil, logical.CodedError(http.StatusBadRequest, fmt.Errorf("master key verification failed: %w", err).Error()) return nil, logical.CodedError(http.StatusBadRequest, fmt.Errorf("rootter key verification failed: %w", err).Error())
} }
} }
// Generate a new key: for AutoUnseal, this is a new master key; for Shamir, // Generate a new key: for AutoUnseal, this is a new root key; for Shamir,
// this is a new unseal key, and performBarrierRekey will also generate a // this is a new unseal key, and performBarrierRekey will also generate a
// new master key. // new root key.
newKey, err := c.barrier.GenerateKey(c.secureRandomReader) newKey, err := c.barrier.GenerateKey(c.secureRandomReader)
if err != nil { if err != nil {
c.logger.Error("failed to generate master key", "error", err) c.logger.Error("failed to generate root key", "error", err)
return nil, logical.CodedError(http.StatusInternalServerError, fmt.Errorf("master key generation failed: %w", err).Error()) return nil, logical.CodedError(http.StatusInternalServerError, fmt.Errorf("root key generation failed: %w", err).Error())
} }
results := &RekeyResult{ results := &RekeyResult{
@ -538,17 +538,17 @@ func (c *Core) performBarrierRekey(ctx context.Context, newSealKey []byte) logic
} }
} }
newMasterKey, err := c.barrier.GenerateKey(c.secureRandomReader) newRootKey, err := c.barrier.GenerateKey(c.secureRandomReader)
if err != nil { if err != nil {
return logical.CodedError(http.StatusInternalServerError, fmt.Errorf("failed to perform rekey: %w", err).Error()) return logical.CodedError(http.StatusInternalServerError, fmt.Errorf("failed to perform rekey: %w", err).Error())
} }
if err := c.seal.SetStoredKeys(ctx, [][]byte{newMasterKey}); err != nil { if err := c.seal.SetStoredKeys(ctx, [][]byte{newRootKey}); err != nil {
c.logger.Error("failed to store keys", "error", err) c.logger.Error("failed to store keys", "error", err)
return logical.CodedError(http.StatusInternalServerError, fmt.Errorf("failed to store keys: %w", err).Error()) return logical.CodedError(http.StatusInternalServerError, fmt.Errorf("failed to store keys: %w", err).Error())
} }
// Rekey the barrier // Rekey the barrier
if err := c.barrier.Rekey(ctx, newMasterKey); err != nil { if err := c.barrier.Rekey(ctx, newRootKey); err != nil {
c.logger.Error("failed to rekey barrier", "error", err) c.logger.Error("failed to rekey barrier", "error", err)
return logical.CodedError(http.StatusInternalServerError, fmt.Errorf("failed to rekey barrier: %w", err).Error()) return logical.CodedError(http.StatusInternalServerError, fmt.Errorf("failed to rekey barrier: %w", err).Error())
} }
@ -655,7 +655,7 @@ func (c *Core) RecoveryRekeyUpdate(ctx context.Context, key []byte, nonce string
return nil, nil return nil, nil
} }
// Recover the master key // Recover the root key
var recoveryKey []byte var recoveryKey []byte
if existingConfig.SecretThreshold == 1 { if existingConfig.SecretThreshold == 1 {
recoveryKey = c.recoveryRekeyConfig.RekeyProgress[0] recoveryKey = c.recoveryRekeyConfig.RekeyProgress[0]
@ -674,23 +674,23 @@ func (c *Core) RecoveryRekeyUpdate(ctx context.Context, key []byte, nonce string
return nil, logical.CodedError(http.StatusBadRequest, fmt.Errorf("recovery key verification failed: %w", err).Error()) return nil, logical.CodedError(http.StatusBadRequest, fmt.Errorf("recovery key verification failed: %w", err).Error())
} }
// Generate a new master key // Generate a new root key
newMasterKey, err := c.barrier.GenerateKey(c.secureRandomReader) newRecoveryKey, err := c.barrier.GenerateKey(c.secureRandomReader)
if err != nil { if err != nil {
c.logger.Error("failed to generate recovery key", "error", err) c.logger.Error("failed to generate recovery key", "error", err)
return nil, logical.CodedError(http.StatusInternalServerError, fmt.Errorf("recovery key generation failed: %w", err).Error()) return nil, logical.CodedError(http.StatusInternalServerError, fmt.Errorf("recovery key generation failed: %w", err).Error())
} }
// Return the master key if only a single key part is used // Return the root key if only a single key part is used
results := &RekeyResult{ results := &RekeyResult{
Backup: c.recoveryRekeyConfig.Backup, Backup: c.recoveryRekeyConfig.Backup,
} }
if c.recoveryRekeyConfig.SecretShares == 1 { if c.recoveryRekeyConfig.SecretShares == 1 {
results.SecretShares = append(results.SecretShares, newMasterKey) results.SecretShares = append(results.SecretShares, newRecoveryKey)
} else { } else {
// Split the master key using the Shamir algorithm // Split the root key using the Shamir algorithm
shares, err := shamir.Split(newMasterKey, c.recoveryRekeyConfig.SecretShares, c.recoveryRekeyConfig.SecretThreshold) shares, err := shamir.Split(newRecoveryKey, c.recoveryRekeyConfig.SecretShares, c.recoveryRekeyConfig.SecretThreshold)
if err != nil { if err != nil {
c.logger.Error("failed to generate shares", "error", err) c.logger.Error("failed to generate shares", "error", err)
return nil, logical.CodedError(http.StatusInternalServerError, fmt.Errorf("failed to generate shares: %w", err).Error()) return nil, logical.CodedError(http.StatusInternalServerError, fmt.Errorf("failed to generate shares: %w", err).Error())
@ -748,14 +748,14 @@ func (c *Core) RecoveryRekeyUpdate(ctx context.Context, key []byte, nonce string
return nil, logical.CodedError(http.StatusInternalServerError, fmt.Errorf("failed to generate verification nonce: %w", err).Error()) return nil, logical.CodedError(http.StatusInternalServerError, fmt.Errorf("failed to generate verification nonce: %w", err).Error())
} }
c.recoveryRekeyConfig.VerificationNonce = nonce c.recoveryRekeyConfig.VerificationNonce = nonce
c.recoveryRekeyConfig.VerificationKey = newMasterKey c.recoveryRekeyConfig.VerificationKey = newRecoveryKey
results.VerificationRequired = true results.VerificationRequired = true
results.VerificationNonce = nonce results.VerificationNonce = nonce
return results, nil return results, nil
} }
if err := c.performRecoveryRekey(ctx, newMasterKey); err != nil { if err := c.performRecoveryRekey(ctx, newRecoveryKey); err != nil {
return nil, logical.CodedError(http.StatusInternalServerError, fmt.Errorf("failed to perform recovery rekey: %w", err).Error()) return nil, logical.CodedError(http.StatusInternalServerError, fmt.Errorf("failed to perform recovery rekey: %w", err).Error())
} }
@ -763,8 +763,8 @@ func (c *Core) RecoveryRekeyUpdate(ctx context.Context, key []byte, nonce string
return results, nil return results, nil
} }
func (c *Core) performRecoveryRekey(ctx context.Context, newMasterKey []byte) logical.HTTPCodedError { func (c *Core) performRecoveryRekey(ctx context.Context, newRootKey []byte) logical.HTTPCodedError {
if err := c.seal.SetRecoveryKey(ctx, newMasterKey); err != nil { if err := c.seal.SetRecoveryKey(ctx, newRootKey); err != nil {
c.logger.Error("failed to set recovery key", "error", err) c.logger.Error("failed to set recovery key", "error", err)
return logical.CodedError(http.StatusInternalServerError, fmt.Errorf("failed to set recovery key: %w", err).Error()) return logical.CodedError(http.StatusInternalServerError, fmt.Errorf("failed to set recovery key: %w", err).Error())
} }
@ -867,7 +867,7 @@ func (c *Core) RekeyVerify(ctx context.Context, key []byte, nonce string, recove
} }
}() }()
// Recover the master key or recovery key // Recover the root key or recovery key
var recoveredKey []byte var recoveredKey []byte
if config.SecretThreshold == 1 { if config.SecretThreshold == 1 {
recoveredKey = config.VerificationProgress[0] recoveredKey = config.VerificationProgress[0]

View File

@ -23,7 +23,7 @@ const (
// barrierSealConfigPath is the path used to store our seal configuration. // barrierSealConfigPath is the path used to store our seal configuration.
// This value is stored in plaintext, since we must be able to read it even // This value is stored in plaintext, since we must be able to read it even
// with the Vault sealed. This is required so that we know how many secret // with the Vault sealed. This is required so that we know how many secret
// parts must be used to reconstruct the master key. // parts must be used to reconstruct the unseal key.
barrierSealConfigPath = "core/seal-config" barrierSealConfigPath = "core/seal-config"
// recoverySealConfigPath is the path to the recovery key seal // recoverySealConfigPath is the path to the recovery key seal
@ -132,7 +132,7 @@ func (d *defaultSeal) StoredKeysSupported() seal.StoredKeysSupport {
case d.LegacySeal(): case d.LegacySeal():
return seal.StoredKeysNotSupported return seal.StoredKeysNotSupported
default: default:
return seal.StoredKeysSupportedShamirMaster return seal.StoredKeysSupportedShamirRoot
} }
} }

View File

@ -15,7 +15,7 @@ const (
StoredKeysInvalid StoredKeysSupport = iota StoredKeysInvalid StoredKeysSupport = iota
StoredKeysNotSupported StoredKeysNotSupported
StoredKeysSupportedGeneric StoredKeysSupportedGeneric
StoredKeysSupportedShamirMaster StoredKeysSupportedShamirRoot
) )
func (s StoredKeysSupport) String() string { func (s StoredKeysSupport) String() string {
@ -24,7 +24,7 @@ func (s StoredKeysSupport) String() string {
return "Old-style Shamir" return "Old-style Shamir"
case StoredKeysSupportedGeneric: case StoredKeysSupportedGeneric:
return "AutoUnseal" return "AutoUnseal"
case StoredKeysSupportedShamirMaster: case StoredKeysSupportedShamirRoot:
return "New-style Shamir" return "New-style Shamir"
default: default:
return "Invalid StoredKeys type" return "Invalid StoredKeys type"

View File

@ -12,7 +12,7 @@ func TestCoreUnsealedWithConfigs(t testing.T, barrierConf, recoveryConf *SealCon
t.Helper() t.Helper()
opts := &seal.TestSealOpts{} opts := &seal.TestSealOpts{}
if recoveryConf == nil { if recoveryConf == nil {
opts.StoredKeys = seal.StoredKeysSupportedShamirMaster opts.StoredKeys = seal.StoredKeysSupportedShamirRoot
} }
return TestCoreUnsealedWithConfigSealOpts(t, barrierConf, recoveryConf, opts) return TestCoreUnsealedWithConfigSealOpts(t, barrierConf, recoveryConf, opts)
} }

View File

@ -19,7 +19,7 @@ func NewTestSeal(t testing.T, opts *seal.TestSealOpts) Seal {
} }
switch opts.StoredKeys { switch opts.StoredKeys {
case seal.StoredKeysSupportedShamirMaster: case seal.StoredKeysSupportedShamirRoot:
newSeal := NewDefaultSeal(&seal.Access{ newSeal := NewDefaultSeal(&seal.Access{
Wrapper: aeadwrapper.NewShamirWrapper(&wrapping.WrapperOptions{ Wrapper: aeadwrapper.NewShamirWrapper(&wrapping.WrapperOptions{
Logger: opts.Logger, Logger: opts.Logger,