From 44c8702bb93a7777ecfa1b921ab65da71b9c77e8 Mon Sep 17 00:00:00 2001 From: Nick Cabatoff Date: Mon, 8 Jun 2020 16:31:46 -0400 Subject: [PATCH 1/5] 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.) --- command/operator_init.go | 14 ++-- command/operator_rekey.go | 6 +- command/operator_seal.go | 4 +- command/operator_unseal.go | 4 +- physical/raft/raft.go | 4 +- vault/barrier.go | 44 ++++++------- vault/barrier_aes_gcm.go | 86 ++++++++++++------------- vault/barrier_test.go | 10 +-- vault/core.go | 110 ++++++++++++++++---------------- vault/generate_root.go | 8 +-- vault/generate_root_recovery.go | 4 +- vault/ha.go | 14 ++-- vault/init.go | 18 +++--- vault/keyring.go | 28 ++++---- vault/keyring_test.go | 14 ++-- vault/logical_system_paths.go | 22 +++---- vault/raft.go | 8 +-- vault/rekey.go | 54 ++++++++-------- vault/seal.go | 4 +- vault/seal/seal.go | 4 +- vault/seal_testing.go | 2 +- vault/seal_testing_util.go | 2 +- 22 files changed, 232 insertions(+), 232 deletions(-) diff --git a/command/operator_init.go b/command/operator_init.go index 5a2c64a8ed4d..775c33af18ea 100644 --- a/command/operator_init.go +++ b/command/operator_init.go @@ -55,10 +55,10 @@ Usage: vault operator init [options] same storage backend in HA mode, you only need to initialize one Vault to initialize the storage backend. - During initialization, Vault generates an in-memory master key and applies - Shamir's secret sharing algorithm to disassemble that master key into a + During initialization, Vault generates an in-memory root key and applies + Shamir's secret sharing algorithm to disassemble that root key into a 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. This command cannot be run against an already-initialized Vault cluster. @@ -103,7 +103,7 @@ func (c *OperatorInitCommand) Flags() *FlagSets { Target: &c.flagKeyShares, Default: defKeyShares, 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.", }) @@ -113,7 +113,7 @@ func (c *OperatorInitCommand) Flags() *FlagSets { Target: &c.flagKeyThreshold, Default: defKeyThreshold, 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.", }) @@ -445,8 +445,8 @@ func (c *OperatorInitCommand) init(client *api.Client, req *api.InitRequest) int c.UI.Output("") c.UI.Output(wrapAtLength(fmt.Sprintf( - "Vault does not store the generated master key. Without at least %d "+ - "key to reconstruct the master key, Vault will remain permanently "+ + "Vault does not store the generated root key. Without at least %d "+ + "key to reconstruct the root key, Vault will remain permanently "+ "sealed!", req.SecretThreshold))) diff --git a/command/operator_rekey.go b/command/operator_rekey.go index d437a9259102..13b0e065efc8 100644 --- a/command/operator_rekey.go +++ b/command/operator_rekey.go @@ -49,7 +49,7 @@ Usage: vault operator rekey [options] [KEY] 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 - 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. An unseal key may be provided directly on the command line as an argument to @@ -127,7 +127,7 @@ func (c *OperatorRekeyCommand) Flags() *FlagSets { Target: &c.flagKeyShares, Default: 5, 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.", }) @@ -137,7 +137,7 @@ func (c *OperatorRekeyCommand) Flags() *FlagSets { Target: &c.flagKeyThreshold, Default: 3, 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.", }) diff --git a/command/operator_seal.go b/command/operator_seal.go index 90161e241c9b..6c09d0a0b0ab 100644 --- a/command/operator_seal.go +++ b/command/operator_seal.go @@ -25,11 +25,11 @@ Usage: vault operator seal [options] Seals the Vault server. Sealing tells the Vault server to stop responding 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. 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. diff --git a/command/operator_unseal.go b/command/operator_unseal.go index c106c1e16678..0c4540eea313 100644 --- a/command/operator_unseal.go +++ b/command/operator_unseal.go @@ -32,9 +32,9 @@ func (c *OperatorUnsealCommand) Help() string { helpText := ` 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 - 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 not recommended as the unseal key will be available in your history: diff --git a/physical/raft/raft.go b/physical/raft/raft.go index c8535ea7cd23..cc94dbefd6d8 100644 --- a/physical/raft/raft.go +++ b/physical/raft/raft.go @@ -813,7 +813,7 @@ func (b *RaftBackend) Peers(ctx context.Context) ([]Peer, error) { // 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 -// 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 *logical.HTTPResponseWriter, access *seal.Access) error { b.l.RLock() defer b.l.RUnlock() @@ -855,7 +855,7 @@ func (b *RaftBackend) Snapshot(out *logical.HTTPResponseWriter, access *seal.Acc // WriteSnapshotToTemp reads a snapshot archive off the provided reader, // 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 -// 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. func (b *RaftBackend) WriteSnapshotToTemp(in io.ReadCloser, access *seal.Access) (*os.File, func(), raft.SnapshotMeta, error) { b.l.RLock() diff --git a/vault/barrier.go b/vault/barrier.go index 92491f7635b4..e833328ce582 100644 --- a/vault/barrier.go +++ b/vault/barrier.go @@ -31,15 +31,15 @@ const ( barrierInitPath = "barrier/init" // keyringPath is the location of the keyring data. This is encrypted - // by the master key. + // by the root key. keyringPath = "core/keyring" keyringPrefix = "core/" // keyringUpgradePrefix is the path used to store keyring update entries. // 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 - // path from key N to N+1. They cannot just use the master key because - // in the event of a rekey, that master key can no longer decrypt the keyring. + // path from key N to N+1. They cannot just use the root key because + // 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 // encryption key N to provide the N+1 key. The standby instances scan // for this periodically and refresh their keyring. The upgrade keys @@ -47,17 +47,17 @@ const ( // standby instances to upgrade without causing any disruption. 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 // 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 - // have the old master key. This key can be decrypted if you have the - // keyring to discover the new master key. The new master key is then + // have the old root key. This key can be decrypted if you have the + // keyring to discover the new root key. The new root key is then // 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 - // 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 // raft snapshots. shamirKekPath = "core/shamir-kek" @@ -71,14 +71,14 @@ const ( // a Vault. The barrier should only be Unlockable given its key. type SecurityBarrier interface { // 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) // Initialize works only if the barrier has not been initialized - // and makes use of the given master key. When sealKey is provided - // it's because we're using a new-style Shamir seal, and masterKey + // and makes use of the given root key. When sealKey is provided + // it's because we're using a new-style Shamir seal, and rootKey // 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(io.Reader) ([]byte, error) @@ -90,27 +90,27 @@ type SecurityBarrier interface { // is not expected to be able to perform any CRUD until it is unsealed. 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. Unseal(ctx context.Context, key []byte) error - // VerifyMaster is used to check if the given key matches the master key - VerifyMaster(key []byte) error + // VerifyRoot is used to check if the given key matches the root key + 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 - // keyring from disk before we have the master key to decrypt it. - SetMasterKey(key []byte) error + // keyring from disk before we have the root key to decrypt it. + SetRootKey(key []byte) error // ReloadKeyring is used to re-read the underlying keyring. // This is used for HA deployments to ensure the latest keyring // is present in the leader. ReloadKeyring(ctx context.Context) error - // ReloadMasterKey is used to re-read the underlying masterkey. - // This is used for HA deployments to ensure the latest master key + // ReloadRootKey is used to re-read the underlying root key. + // This is used for HA deployments to ensure the latest root key // 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 // be unsealed again to perform any further operations. @@ -132,7 +132,7 @@ type SecurityBarrier interface { // ActiveKeyInfo is used to inform details about the active key ActiveKeyInfo() (*KeyInfo, error) - // 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 Rekey(context.Context, []byte) error // For replication we must send over the keyring, so this must be available diff --git a/vault/barrier_aes_gcm.go b/vault/barrier_aes_gcm.go index fa2fc22a7946..dea142cb6367 100644 --- a/vault/barrier_aes_gcm.go +++ b/vault/barrier_aes_gcm.go @@ -88,7 +88,7 @@ func NewAESGCMBarrier(physical physical.Backend) (*AESGCMBarrier, error) { } // 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) { if b.initialized.Load() { return true, nil @@ -114,7 +114,7 @@ func (b *AESGCMBarrier) Initialized(ctx context.Context) (bool, error) { } // 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 { // Verify the key size min, max := b.KeyLength() @@ -137,7 +137,7 @@ func (b *AESGCMBarrier) Initialize(ctx context.Context, key, sealKey []byte, rea // Create a new keyring, install the keys keyring := NewKeyring() - keyring = keyring.SetMasterKey(key) + keyring = keyring.SetRootKey(key) keyring, err = keyring.AddKey(&Key{ Term: 1, Version: 1, @@ -171,7 +171,7 @@ func (b *AESGCMBarrier) Initialize(ctx context.Context, key, sealKey []byte, rea } // 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 { // Create the keyring entry keyringBuf, err := keyring.Serialize() @@ -181,7 +181,7 @@ func (b *AESGCMBarrier) persistKeyring(ctx context.Context, keyring *Keyring) er } // Create the AES-GCM - gcm, err := b.aeadFromKey(keyring.MasterKey()) + gcm, err := b.aeadFromKey(keyring.RootKey()) if err != nil { return err } @@ -201,36 +201,36 @@ func (b *AESGCMBarrier) persistKeyring(ctx context.Context, keyring *Keyring) er return errwrap.Wrapf("failed to persist keyring: {{err}}", err) } - // Serialize the master key value + // Serialize the root key value key := &Key{ Term: 1, Version: 1, - Value: keyring.MasterKey(), + Value: keyring.RootKey(), } keyBuf, err := key.Serialize() defer memzero(keyBuf) if err != nil { - return errwrap.Wrapf("failed to serialize master key: {{err}}", err) + return errwrap.Wrapf("failed to serialize root key: {{err}}", err) } - // Encrypt the master key + // Encrypt the root key activeKey := keyring.ActiveKey() aead, err := b.aeadFromKey(activeKey.Value) if err != nil { return err } - value, err = b.encrypt(masterKeyPath, activeKey.Term, aead, keyBuf) + value, err = b.encrypt(rootKeyPath, activeKey.Term, aead, keyBuf) if err != nil { return err } - // Update the masterKeyPath for standby instances + // Update the rootKeyPath for standby instances pe = &physical.Entry{ - Key: masterKeyPath, + Key: rootKeyPath, Value: value, } if err := b.backend.Put(ctx, pe); err != nil { - return errwrap.Wrapf("failed to persist master key: {{err}}", err) + return errwrap.Wrapf("failed to persist root key: {{err}}", err) } return nil } @@ -258,14 +258,14 @@ func (b *AESGCMBarrier) Sealed() (bool, error) { return sealed, nil } -// VerifyMaster is used to check if the given key matches the master key -func (b *AESGCMBarrier) VerifyMaster(key []byte) error { +// VerifyRoot is used to check if the given key matches the root key +func (b *AESGCMBarrier) VerifyRoot(key []byte) error { b.l.RLock() defer b.l.RUnlock() if b.sealed { return ErrBarrierSealed } - if subtle.ConstantTimeCompare(key, b.keyring.MasterKey()) != 1 { + if subtle.ConstantTimeCompare(key, b.keyring.RootKey()) != 1 { return ErrBarrierInvalidKey } return nil @@ -279,7 +279,7 @@ func (b *AESGCMBarrier) ReloadKeyring(ctx context.Context) error { defer b.l.Unlock() // Create the AES-GCM - gcm, err := b.aeadFromKey(b.keyring.MasterKey()) + gcm, err := b.aeadFromKey(b.keyring.RootKey()) if err != nil { return err } @@ -324,19 +324,19 @@ func (b *AESGCMBarrier) ReloadKeyring(ctx context.Context) error { return nil } -// ReloadMasterKey is used to re-read the underlying masterkey. -// This is used for HA deployments to ensure the latest master key +// ReloadRootKey is used to re-read the underlying root key. +// This is used for HA deployments to ensure the latest root key // is available for keyring reloading. -func (b *AESGCMBarrier) ReloadMasterKey(ctx context.Context) error { - // Read the masterKeyPath upgrade - out, err := b.Get(ctx, masterKeyPath) +func (b *AESGCMBarrier) ReloadRootKey(ctx context.Context) error { + // Read the rootKeyPath upgrade + out, err := b.Get(ctx, rootKeyPath) if err != nil { - return errwrap.Wrapf("failed to read master key path: {{err}}", err) + return errwrap.Wrapf("failed to read root key path: {{err}}", 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 - // master key. + // root key. if out == nil { return nil } @@ -345,35 +345,35 @@ func (b *AESGCMBarrier) ReloadMasterKey(ctx context.Context) error { b.l.Lock() defer b.l.Unlock() - out, err = b.lockSwitchedGet(ctx, masterKeyPath, false) + out, err = b.lockSwitchedGet(ctx, rootKeyPath, false) if err != nil { - return errwrap.Wrapf("failed to read master key path: {{err}}", err) + return errwrap.Wrapf("failed to read root key path: {{err}}", err) } if out == nil { return nil } - // Deserialize the master key + // Deserialize the root key key, err := DeserializeKey(out.Value) memzero(out.Value) if err != nil { return errwrap.Wrapf("failed to deserialize key: {{err}}", err) } - // Check if the master key is the same - if subtle.ConstantTimeCompare(b.keyring.MasterKey(), key.Value) == 1 { + // Check if the root key is the same + if subtle.ConstantTimeCompare(b.keyring.RootKey(), key.Value) == 1 { return nil } - // Update the master key + // Update the root key oldKeyring := b.keyring - b.keyring = b.keyring.SetMasterKey(key.Value) + b.keyring = b.keyring.SetRootKey(key.Value) oldKeyring.Zeroize(false) 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. func (b *AESGCMBarrier) Unseal(ctx context.Context, key []byte) error { b.l.Lock() @@ -457,9 +457,9 @@ func (b *AESGCMBarrier) Unseal(ctx context.Context, key []byte) error { // Setup a new keyring, this is for backwards compatibility 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) keyring, err = keyring.AddKey(&Key{ @@ -669,12 +669,12 @@ func (b *AESGCMBarrier) ActiveKeyInfo() (*KeyInfo, error) { 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 { b.l.Lock() defer b.l.Unlock() - newKeyring, err := b.updateMasterKeyCommon(key) + newKeyring, err := b.updateRootKeyCommon(key) if err != nil { return err } @@ -691,13 +691,13 @@ func (b *AESGCMBarrier) Rekey(ctx context.Context, key []byte) error { 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 -func (b *AESGCMBarrier) SetMasterKey(key []byte) error { +func (b *AESGCMBarrier) SetRootKey(key []byte) error { b.l.Lock() defer b.l.Unlock() - newKeyring, err := b.updateMasterKeyCommon(key) + newKeyring, err := b.updateRootKeyCommon(key) if err != nil { return err } @@ -709,9 +709,9 @@ func (b *AESGCMBarrier) SetMasterKey(key []byte) error { 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 -func (b *AESGCMBarrier) updateMasterKeyCommon(key []byte) (*Keyring, error) { +func (b *AESGCMBarrier) updateRootKeyCommon(key []byte) (*Keyring, error) { if b.sealed { return nil, ErrBarrierSealed } @@ -722,7 +722,7 @@ func (b *AESGCMBarrier) updateMasterKeyCommon(key []byte) (*Keyring, error) { 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 diff --git a/vault/barrier_test.go b/vault/barrier_test.go index 5468fce3eefe..9fb65aa5742b 100644 --- a/vault/barrier_test.go +++ b/vault/barrier_test.go @@ -117,7 +117,7 @@ func testBarrier(t *testing.T, b SecurityBarrier) { } // Verify the master key - if err := b.VerifyMaster(key); err != nil { + if err := b.VerifyRoot(key); err != nil { t.Fatalf("err: %v", err) } @@ -366,7 +366,7 @@ func testBarrier_Rekey(t *testing.T, b SecurityBarrier) { } // Verify the master key - if err := b.VerifyMaster(key); err != nil { + if err := b.VerifyRoot(key); err != nil { t.Fatalf("err: %v", err) } @@ -378,12 +378,12 @@ func testBarrier_Rekey(t *testing.T, b SecurityBarrier) { } // Verify the old master key - if err := b.VerifyMaster(key); err != ErrBarrierInvalidKey { + if err := b.VerifyRoot(key); err != ErrBarrierInvalidKey { t.Fatalf("err: %v", err) } // Verify the new master key - if err := b.VerifyMaster(newKey); err != nil { + if err := b.VerifyRoot(newKey); err != nil { t.Fatalf("err: %v", err) } @@ -522,7 +522,7 @@ func testBarrier_Upgrade_Rekey(t *testing.T, b1, b2 SecurityBarrier) { } // Reload the master key - err = b2.ReloadMasterKey(context.Background()) + err = b2.ReloadRootKey(context.Background()) if err != nil { t.Fatalf("err: %v", err) } diff --git a/vault/core.go b/vault/core.go index 6fc6d850cf80..f0b2887e6bf2 100644 --- a/vault/core.go +++ b/vault/core.go @@ -169,10 +169,10 @@ type migrationInformation struct { // seal to use during a migration operation. It is the // seal we're migrating *from*. seal Seal - masterKey []byte + rootKey []byte recoveryKey []byte - // shamirCombinedKey is the key that is used to store master key when shamir + // shamirCombinedKey is the key that is used to store root key when shamir // seal is in use. This will be set as the recovery key when a migration happens // from shamir to auto-seal. shamirCombinedKey []byte @@ -274,13 +274,13 @@ type Core struct { unlockInfo *unlockInformation // generateRootProgress holds the shares until we reach enough - // to verify the master key + // to verify the root key generateRootConfig *GenerateRootConfig generateRootProgress [][]byte generateRootLock sync.Mutex // These variables holds the config and shares we have until we reach - // enough to verify the appropriate master key. Note that the same lock is + // enough to verify the appropriate root key. Note that the same lock is // used; this isn't time-critical so this shouldn't be a problem. barrierRekeyConfig *SealConfig recoveryRekeyConfig *SealConfig @@ -1059,18 +1059,18 @@ func (c *Core) unseal(key []byte, useRecoveryKeys bool) (bool, error) { sealToUse = c.migrationInfo.seal } - // unsealPart returns either a master key (legacy shamir) or an unseal + // unsealPart returns either a root key (legacy shamir) or an unseal // key (new-style shamir). - masterKey, err := c.unsealPart(ctx, sealToUse, key, useRecoveryKeys) + rootKey, err := c.unsealPart(ctx, sealToUse, key, useRecoveryKeys) if err != nil { return false, err } - if masterKey != nil { + if rootKey != nil { if sealToUse.BarrierType() == wrapping.Shamir && c.migrationInfo == nil { // If this is a legacy shamir seal this serves no purpose but it // doesn't hurt. - err = sealToUse.GetAccess().Wrapper.(*aeadwrapper.ShamirWrapper).SetAESGCMKeyBytes(masterKey) + err = sealToUse.GetAccess().Wrapper.(*aeadwrapper.ShamirWrapper).SetAESGCMKeyBytes(rootKey) if err != nil { return false, err } @@ -1086,7 +1086,7 @@ func (c *Core) unseal(key []byte, useRecoveryKeys bool) (bool, error) { // If there is a stored key, retrieve it. if cfg.StoredShares > 0 { // Here's where we actually test that the provided unseal - // key is valid: can it decrypt the stored master key? + // key is valid: can it decrypt the stored root key? storedKeys, err := sealToUse.GetStoredKeys(ctx) if err != nil { return false, err @@ -1094,11 +1094,11 @@ func (c *Core) unseal(key []byte, useRecoveryKeys bool) (bool, error) { if len(storedKeys) == 0 { return false, fmt.Errorf("shamir seal with stored keys configured but no stored keys found") } - masterKey = storedKeys[0] + rootKey = storedKeys[0] } } - return c.unsealInternal(ctx, masterKey) + return c.unsealInternal(ctx, rootKey) } switch c.raftInfo.joinInProgress { @@ -1124,10 +1124,10 @@ func (c *Core) unseal(key []byte, useRecoveryKeys bool) (bool, error) { go func() { keyringFound := false - haveMasterKey := sealToUse.StoredKeysSupported() != vaultseal.StoredKeysSupportedShamirMaster + haveRootKey := sealToUse.StoredKeysSupported() != vaultseal.StoredKeysSupportedShamirRoot defer func() { - if keyringFound && haveMasterKey { - _, err := c.unsealInternal(ctx, masterKey) + if keyringFound && haveRootKey { + _, err := c.unsealInternal(ctx, rootKey) if err != nil { c.logger.Error("failed to unseal", "error", err) } @@ -1147,18 +1147,18 @@ func (c *Core) unseal(key []byte, useRecoveryKeys bool) (bool, error) { keyringFound = true } } - if !haveMasterKey { + if !haveRootKey { keys, err := sealToUse.GetStoredKeys(ctx) if err != nil { - c.logger.Error("failed to read master key", "error", err) + c.logger.Error("failed to read root key", "error", err) return } if len(keys) > 0 { - haveMasterKey = true - masterKey = keys[0] + haveRootKey = true + rootKey = keys[0] } } - if keyringFound && haveMasterKey { + if keyringFound && haveRootKey { return } time.Sleep(1 * time.Second) @@ -1174,7 +1174,7 @@ func (c *Core) unseal(key []byte, useRecoveryKeys bool) (bool, error) { return false, nil } -// unsealPart takes in a key share, and returns the master key if the threshold +// unsealPart takes in a key share, and returns the root key if the threshold // is met. If recovery keys are supported, recovery key shares may be provided. func (c *Core) unsealPart(ctx context.Context, seal Seal, key []byte, useRecoveryKeys bool) ([]byte, error) { // Check if we already have this piece @@ -1234,7 +1234,7 @@ func (c *Core) unsealPart(ctx context.Context, seal Seal, key []byte, useRecover // Recover the split key. recoveredKey is the shamir combined // key, or the single provided key if the threshold is 1. var recoveredKey []byte - var masterKey []byte + var rootKey []byte var recoveryKey []byte if config.SecretThreshold == 1 { recoveredKey = make([]byte, len(c.unlockInfo.Parts[0])) @@ -1242,7 +1242,7 @@ func (c *Core) unsealPart(ctx context.Context, seal Seal, key []byte, useRecover } else { recoveredKey, err = shamir.Combine(c.unlockInfo.Parts) if err != nil { - return nil, errwrap.Wrapf("failed to compute master key: {{err}}", err) + return nil, errwrap.Wrapf("failed to compute root key: {{err}}", err) } } @@ -1253,31 +1253,31 @@ func (c *Core) unsealPart(ctx context.Context, seal Seal, key []byte, useRecover } recoveryKey = recoveredKey - // Get stored keys and shamir combine into single master key. Unsealing with + // Get stored keys and shamir combine into single root key. Unsealing with // recovery keys currently does not support: 1) mixed stored and non-stored // keys setup, nor 2) seals that support recovery keys but not stored keys. // If insufficient shares are provided, shamir.Combine will error, and if - // no stored keys are found it will return masterKey as nil. + // no stored keys are found it will return rootKey as nil. if seal.StoredKeysSupported() == vaultseal.StoredKeysSupportedGeneric { - masterKeyShares, err := seal.GetStoredKeys(ctx) + rootKeyShares, err := seal.GetStoredKeys(ctx) if err != nil { return nil, errwrap.Wrapf("unable to retrieve stored keys: {{err}}", err) } - switch len(masterKeyShares) { + switch len(rootKeyShares) { case 0: - return nil, errors.New("seal returned no master key shares") + return nil, errors.New("seal returned no root key shares") case 1: - masterKey = masterKeyShares[0] + rootKey = rootKeyShares[0] default: - masterKey, err = shamir.Combine(masterKeyShares) + rootKey, err = shamir.Combine(rootKeyShares) if err != nil { - return nil, errwrap.Wrapf("failed to compute master key: {{err}}", err) + return nil, errwrap.Wrapf("failed to compute root key: {{err}}", err) } } } } else { - masterKey = recoveredKey + rootKey = recoveredKey } switch { @@ -1286,24 +1286,24 @@ func (c *Core) unsealPart(ctx context.Context, seal Seal, key []byte, useRecover // avoid accidental reference changes c.migrationInfo.shamirCombinedKey = make([]byte, len(recoveredKey)) copy(c.migrationInfo.shamirCombinedKey, recoveredKey) - if seal.StoredKeysSupported() == vaultseal.StoredKeysSupportedShamirMaster { + if seal.StoredKeysSupported() == vaultseal.StoredKeysSupportedShamirRoot { err = seal.GetAccess().Wrapper.(*aeadwrapper.ShamirWrapper).SetAESGCMKeyBytes(recoveredKey) if err != nil { - return nil, errwrap.Wrapf("failed to set master key in seal: {{err}}", err) + return nil, errwrap.Wrapf("failed to set root key in seal: {{err}}", err) } storedKeys, err := seal.GetStoredKeys(ctx) if err != nil { return nil, errwrap.Wrapf("unable to retrieve stored keys: {{err}}", err) } - masterKey = storedKeys[0] + rootKey = storedKeys[0] } - c.migrationInfo.masterKey = make([]byte, len(masterKey)) - copy(c.migrationInfo.masterKey, masterKey) + c.migrationInfo.rootKey = make([]byte, len(rootKey)) + copy(c.migrationInfo.rootKey, rootKey) c.migrationInfo.recoveryKey = make([]byte, len(recoveryKey)) copy(c.migrationInfo.recoveryKey, recoveryKey) } - return masterKey, nil + return rootKey, nil } func (c *Core) migrateSeal(ctx context.Context) error { @@ -1363,35 +1363,35 @@ func (c *Core) migrateSeal(ctx context.Context) error { // shamir KeK. err := c.seal.GetAccess().Wrapper.(*aeadwrapper.ShamirWrapper).SetAESGCMKeyBytes(c.migrationInfo.recoveryKey) if err != nil { - return errwrap.Wrapf("failed to set master key in seal: {{err}}", err) + return errwrap.Wrapf("failed to set root key in seal: {{err}}", err) } - if err := c.seal.SetStoredKeys(ctx, [][]byte{c.migrationInfo.masterKey}); err != nil { + if err := c.seal.SetStoredKeys(ctx, [][]byte{c.migrationInfo.rootKey}); err != nil { return errwrap.Wrapf("error setting new barrier key information during migrate: {{err}}", err) } case c.seal.RecoveryKeySupported(): c.logger.Info("migrating from shamir to auto-unseal", "to", c.seal.BarrierType()) // Migration is happening from shamir -> auto. In this case use the shamir - // combined key that was used to store the master key as the new recovery key. + // combined key that was used to store the root key as the new recovery key. if err := c.seal.SetRecoveryKey(ctx, c.migrationInfo.shamirCombinedKey); err != nil { return errwrap.Wrapf("error setting new recovery key information: {{err}}", err) } - // Generate a new master key - newMasterKey, err := c.barrier.GenerateKey(c.secureRandomReader) + // Generate a new root key + newRootKey, err := c.barrier.GenerateKey(c.secureRandomReader) if err != nil { - return errwrap.Wrapf("error generating new master key: {{err}}", err) + return errwrap.Wrapf("error generating new root key: {{err}}", err) } // Rekey the barrier - if err := c.barrier.Rekey(ctx, newMasterKey); err != nil { + if err := c.barrier.Rekey(ctx, newRootKey); err != nil { return errwrap.Wrapf("error rekeying barrier during migration: {{err}}", err) } - // Store the new master key - if err := c.seal.SetStoredKeys(ctx, [][]byte{newMasterKey}); err != nil { - return errwrap.Wrapf("error storing new master key: {{err}}", err) + // Store the new root key + if err := c.seal.SetStoredKeys(ctx, [][]byte{newRootKey}); err != nil { + return errwrap.Wrapf("error storing new root key: {{err}}", err) } default: @@ -1429,13 +1429,13 @@ func (c *Core) migrateSeal(ctx context.Context) error { return nil } -// unsealInternal takes in the master key and attempts to unseal the barrier. +// unsealInternal takes in the root key and attempts to unseal the barrier. // N.B.: This must be called with the state write lock held. -func (c *Core) unsealInternal(ctx context.Context, masterKey []byte) (bool, error) { - defer memzero(masterKey) +func (c *Core) unsealInternal(ctx context.Context, rootKey []byte) (bool, error) { + defer memzero(rootKey) // Attempt to unlock - if err := c.barrier.Unseal(ctx, masterKey); err != nil { + if err := c.barrier.Unseal(ctx, rootKey); err != nil { return false, err } @@ -2243,11 +2243,11 @@ func (c *Core) SetSealsForMigration(migrationSeal, newSeal, unwrapSeal Seal) { } } -// unsealKeyToMasterKey takes a key provided by the user, either a recovery key +// unsealKeyToRootKey takes a key provided by the user, either a recovery key // if using an autoseal or an unseal key with Shamir. It returns a nil error -// if the key is valid and an error otherwise. It also returns the master key +// if the key is valid and an error otherwise. It also returns the root key // that can be used to unseal the barrier. -func (c *Core) unsealKeyToMasterKey(ctx context.Context, combinedKey []byte) ([]byte, error) { +func (c *Core) unsealKeyToRootKey(ctx context.Context, combinedKey []byte) ([]byte, error) { switch c.seal.StoredKeysSupported() { case vaultseal.StoredKeysSupportedGeneric: if err := c.seal.VerifyRecoveryKey(ctx, combinedKey); err != nil { @@ -2263,7 +2263,7 @@ func (c *Core) unsealKeyToMasterKey(ctx context.Context, combinedKey []byte) ([] } return storedKeys[0], nil - case vaultseal.StoredKeysSupportedShamirMaster: + case vaultseal.StoredKeysSupportedShamirRoot: testseal := NewDefaultSeal(&vaultseal.Access{ Wrapper: aeadwrapper.NewShamirWrapper(&wrapping.WrapperOptions{ Logger: c.logger.Named("testseal"), diff --git a/vault/generate_root.go b/vault/generate_root.go index ca8ab54e6669..254f6793ac65 100644 --- a/vault/generate_root.go +++ b/vault/generate_root.go @@ -39,12 +39,12 @@ type GenerateRootStrategy interface { type generateStandardRootToken struct{} func (g generateStandardRootToken) authenticate(ctx context.Context, c *Core, combinedKey []byte) error { - masterKey, err := c.unsealKeyToMasterKey(ctx, combinedKey) + rootKey, err := c.unsealKeyToRootKey(ctx, combinedKey) if err != nil { return errwrap.Wrapf("unable to authenticate: {{err}}", err) } - if err := c.barrier.VerifyMaster(masterKey); err != nil { - return errwrap.Wrapf("master key verification failed: {{err}}", err) + if err := c.barrier.VerifyRoot(rootKey); err != nil { + return errwrap.Wrapf("root key verification failed: {{err}}", err) } return nil @@ -304,7 +304,7 @@ func (c *Core) GenerateRootUpdate(ctx context.Context, key []byte, nonce string, combinedKey, err = shamir.Combine(c.generateRootProgress) c.generateRootProgress = nil if err != nil { - return nil, errwrap.Wrapf("failed to compute master key: {{err}}", err) + return nil, errwrap.Wrapf("failed to compute root key: {{err}}", err) } } diff --git a/vault/generate_root_recovery.go b/vault/generate_root_recovery.go index e677802e28c8..b86c28017903 100644 --- a/vault/generate_root_recovery.go +++ b/vault/generate_root_recovery.go @@ -21,12 +21,12 @@ type generateRecoveryToken struct { } func (g *generateRecoveryToken) authenticate(ctx context.Context, c *Core, combinedKey []byte) error { - key, err := c.unsealKeyToMasterKey(ctx, combinedKey) + key, err := c.unsealKeyToRootKey(ctx, combinedKey) if err != nil { return errwrap.Wrapf("unable to authenticate: {{err}}", 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 { return errwrap.Wrapf("recovery operation token generation failed, cannot unseal barrier: {{err}}", err) } diff --git a/vault/ha.go b/vault/ha.go index 63ea7e84daca..4cb121a5ae65 100644 --- a/vault/ha.go +++ b/vault/ha.go @@ -785,9 +785,9 @@ func (c *Core) checkKeyUpgrades(ctx context.Context) error { return nil } -func (c *Core) reloadMasterKey(ctx context.Context) error { - if err := c.barrier.ReloadMasterKey(ctx); err != nil { - return errwrap.Wrapf("error reloading master key: {{err}}", err) +func (c *Core) reloadRootKey(ctx context.Context) error { + if err := c.barrier.ReloadRootKey(ctx); err != nil { + return errwrap.Wrapf("error reloading root key: {{err}}", err) } return nil } @@ -801,7 +801,7 @@ func (c *Core) reloadShamirKey(ctx context.Context) error { switch c.seal.StoredKeysSupported() { case seal.StoredKeysSupportedGeneric: return nil - case seal.StoredKeysSupportedShamirMaster: + case seal.StoredKeysSupportedShamirRoot: entry, err := c.barrier.Get(ctx, shamirKekPath) if err != nil { return err @@ -815,7 +815,7 @@ func (c *Core) reloadShamirKey(ctx context.Context) error { if err != nil { return errwrap.Wrapf("failed to update seal access: {{err}}", err) } - shamirKey = keyring.masterKey + shamirKey = keyring.rootKey } return c.seal.GetAccess().Wrapper.(*aeadwrapper.ShamirWrapper).SetAESGCMKeyBytes(shamirKey) } @@ -825,8 +825,8 @@ func (c *Core) performKeyUpgrades(ctx context.Context) error { return errwrap.Wrapf("error checking for key upgrades: {{err}}", err) } - if err := c.reloadMasterKey(ctx); err != nil { - return errwrap.Wrapf("error reloading master key: {{err}}", err) + if err := c.reloadRootKey(ctx); err != nil { + return errwrap.Wrapf("error reloading root key: {{err}}", err) } if err := c.barrier.ReloadKeyring(ctx); err != nil { diff --git a/vault/init.go b/vault/init.go index 2fd8a2548f66..629f0925eea8 100644 --- a/vault/init.go +++ b/vault/init.go @@ -95,19 +95,19 @@ func (c *Core) Initialized(ctx context.Context) (bool, error) { } func (c *Core) generateShares(sc *SealConfig) ([]byte, [][]byte, error) { - // Generate a master key - masterKey, err := c.barrier.GenerateKey(c.secureRandomReader) + // Generate a root key + rootKey, err := c.barrier.GenerateKey(c.secureRandomReader) if err != nil { return nil, nil, errwrap.Wrapf("key generation failed: {{err}}", 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 if sc.SecretShares == 1 { - unsealKeys = append(unsealKeys, masterKey) + unsealKeys = append(unsealKeys, rootKey) } else { - // Split the master key using the Shamir algorithm - shares, err := shamir.Split(masterKey, sc.SecretShares, sc.SecretThreshold) + // Split the root key using the Shamir algorithm + shares, err := shamir.Split(rootKey, sc.SecretShares, sc.SecretThreshold) if err != nil { return nil, nil, errwrap.Wrapf("failed to generate barrier shares: {{err}}", err) } @@ -127,7 +127,7 @@ func (c *Core) generateShares(sc *SealConfig) ([]byte, [][]byte, error) { unsealKeys = encryptedShares } - return masterKey, unsealKeys, nil + return rootKey, unsealKeys, nil } // Initialize is used to initialize the Vault with the given @@ -141,7 +141,7 @@ func (c *Core) Initialize(ctx context.Context, initParams *InitParams) (*InitRes // 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 // 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, // 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 @@ -301,7 +301,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 // them through the seal switch c.seal.StoredKeysSupported() { - case seal.StoredKeysSupportedShamirMaster: + case seal.StoredKeysSupportedShamirRoot: keysToStore := [][]byte{barrierKey} if err := c.seal.GetAccess().Wrapper.(*aeadwrapper.ShamirWrapper).SetAESGCMKeyBytes(sealKey); err != nil { c.logger.Error("failed to set seal key", "error", err) diff --git a/vault/keyring.go b/vault/keyring.go index 9c488715ca37..2a8547b9ce7a 100644 --- a/vault/keyring.go +++ b/vault/keyring.go @@ -15,11 +15,11 @@ import ( // 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 // allows for decryption of keys written previously. Along with the encryption -// keys, the keyring also tracks the master key. This is necessary so that -// when a new key is added to the keyring, we can encrypt with the master key +// 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 root key // and write out the new keyring. type Keyring struct { - masterKey []byte + rootKey []byte keys map[uint32]*Key activeTerm uint32 } @@ -64,7 +64,7 @@ func NewKeyring() *Keyring { // Clone returns a new copy of the keyring func (k *Keyring) Clone() *Keyring { clone := &Keyring{ - masterKey: k.masterKey, + rootKey: k.rootKey, keys: make(map[uint32]*Key, len(k.keys)), activeTerm: k.activeTerm, } @@ -135,25 +135,25 @@ func (k *Keyring) TermKey(term uint32) *Key { return k.keys[term] } -// SetMasterKey is used to update the master key -func (k *Keyring) SetMasterKey(val []byte) *Keyring { +// SetRootKey is used to update the root key +func (k *Keyring) SetRootKey(val []byte) *Keyring { valCopy := make([]byte, len(val)) copy(valCopy, val) clone := k.Clone() - clone.masterKey = valCopy + clone.rootKey = valCopy return clone } -// MasterKey returns the master key -func (k *Keyring) MasterKey() []byte { - return k.masterKey +// RootKey returns the root key +func (k *Keyring) RootKey() []byte { + return k.rootKey } // Serialize is used to create a byte encoded keyring func (k *Keyring) Serialize() ([]byte, error) { // Create the encoded entry enc := EncodedKeyring{ - MasterKey: k.masterKey, + MasterKey: k.rootKey, } for _, key := range k.keys { enc.Keys = append(enc.Keys, key) @@ -174,7 +174,7 @@ func DeserializeKeyring(buf []byte) (*Keyring, error) { // Create a new keyring k := NewKeyring() - k.masterKey = enc.MasterKey + k.rootKey = enc.MasterKey for _, key := range enc.Keys { k.keys[key.Term] = key if key.Term > k.activeTerm { @@ -191,8 +191,8 @@ func (k *Keyring) Zeroize(keysToo bool) { if k == nil { return } - if k.masterKey != nil { - memzero(k.masterKey) + if k.rootKey != nil { + memzero(k.rootKey) } if !keysToo || k.keys == nil { return diff --git a/vault/keyring_test.go b/vault/keyring_test.go index aaac35b61901..bb6a5047598d 100644 --- a/vault/keyring_test.go +++ b/vault/keyring_test.go @@ -113,21 +113,21 @@ func TestKeyring_MasterKey(t *testing.T) { master2 := []byte("test2") // Check no master - out := k.MasterKey() + out := k.RootKey() if out != nil { t.Fatalf("bad: %v", out) } // Set master - k = k.SetMasterKey(master) - out = k.MasterKey() + k = k.SetRootKey(master) + out = k.RootKey() if !bytes.Equal(out, master) { t.Fatalf("bad: %v", out) } // Update master - k = k.SetMasterKey(master2) - out = k.MasterKey() + k = k.SetRootKey(master2) + out = k.RootKey() if !bytes.Equal(out, master2) { t.Fatalf("bad: %v", out) } @@ -136,7 +136,7 @@ func TestKeyring_MasterKey(t *testing.T) { func TestKeyring_Serialize(t *testing.T) { k := NewKeyring() master := []byte("test") - k = k.SetMasterKey(master) + k = k.SetRootKey(master) now := time.Now() testKey := []byte("testing") @@ -154,7 +154,7 @@ func TestKeyring_Serialize(t *testing.T) { t.Fatalf("err: %v", err) } - out := k2.MasterKey() + out := k2.RootKey() if !bytes.Equal(out, master) { t.Fatalf("bad: %v", out) } diff --git a/vault/logical_system_paths.go b/vault/logical_system_paths.go index eb36e4f37f15..baa10fec26f0 100644 --- a/vault/logical_system_paths.go +++ b/vault/logical_system_paths.go @@ -135,7 +135,7 @@ func (b *SystemBackend) configPaths() []*framework.Path { Fields: map[string]*framework.FieldSchema{ "key": &framework.FieldSchema{ Type: framework.TypeString, - Description: "Specifies a single master key share.", + Description: "Specifies a single unseal key share.", }, "nonce": &framework.FieldSchema{ Type: framework.TypeString, @@ -144,8 +144,8 @@ func (b *SystemBackend) configPaths() []*framework.Path { }, Operations: map[logical.Operation]framework.OperationHandler{ logical.UpdateOperation: &framework.PathOperation{ - Summary: "Enter a single master 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.", + Summary: "Enter a single unseal key share to progress the root generation attempt.", + 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.", }, }, @@ -218,11 +218,11 @@ func (b *SystemBackend) configPaths() []*framework.Path { }, "secret_shares": &framework.FieldSchema{ 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": &framework.FieldSchema{ 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": &framework.FieldSchema{ Type: framework.TypeInt, @@ -289,11 +289,11 @@ func (b *SystemBackend) rekeyPaths() []*framework.Path { Fields: map[string]*framework.FieldSchema{ "secret_shares": &framework.FieldSchema{ 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": &framework.FieldSchema{ 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": &framework.FieldSchema{ Type: framework.TypeCommaStringSlice, @@ -362,7 +362,7 @@ func (b *SystemBackend) rekeyPaths() []*framework.Path { Fields: map[string]*framework.FieldSchema{ "key": &framework.FieldSchema{ Type: framework.TypeString, - Description: "Specifies a single master key share.", + Description: "Specifies a single unseal key share.", }, "nonce": &framework.FieldSchema{ Type: framework.TypeString, @@ -372,7 +372,7 @@ func (b *SystemBackend) rekeyPaths() []*framework.Path { Operations: map[logical.Operation]framework.OperationHandler{ 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.", }, }, }, @@ -382,7 +382,7 @@ func (b *SystemBackend) rekeyPaths() []*framework.Path { Fields: map[string]*framework.FieldSchema{ "key": &framework.FieldSchema{ 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": &framework.FieldSchema{ Type: framework.TypeString, @@ -432,7 +432,7 @@ func (b *SystemBackend) rekeyPaths() []*framework.Path { Fields: map[string]*framework.FieldSchema{ "key": &framework.FieldSchema{ 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": &framework.FieldSchema{ Type: framework.TypeBool, diff --git a/vault/raft.go b/vault/raft.go index 8c912451678c..e1060b0b94a3 100644 --- a/vault/raft.go +++ b/vault/raft.go @@ -467,7 +467,7 @@ func (c *Core) checkRaftTLSKeyUpgrades(ctx context.Context) error { // 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 -// keyrings or master keys +// keyrings or root keys func (c *Core) raftSnapshotRestoreCallback(grabLock bool, sealNode bool) func(context.Context) error { return func(ctx context.Context) (retErr error) { c.logger.Info("running post snapshot restore invalidations") @@ -503,10 +503,10 @@ func (c *Core) raftSnapshotRestoreCallback(grabLock bool, sealNode bool) func(co } // 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) 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 switch c.seal.BarrierType() { case wrapping.Shamir: @@ -535,7 +535,7 @@ func (c *Core) raftSnapshotRestoreCallback(grabLock bool, sealNode bool) func(co c.logger.Error("raft snapshot restore failed to unseal barrier", "error", err) return err } - c.logger.Info("done reloading master key using auto seal") + c.logger.Info("done reloading root key using auto seal") } } diff --git a/vault/rekey.go b/vault/rekey.go index bc5aba05c7c5..d066fc6c683b 100644 --- a/vault/rekey.go +++ b/vault/rekey.go @@ -332,7 +332,7 @@ func (c *Core) BarrierRekeyUpdate(ctx context.Context, key []byte, nonce string) // Get the seal configuration var existingConfig *SealConfig 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() { existingConfig, err = c.seal.RecoveryConfig(ctx) useRecovery = true @@ -378,7 +378,7 @@ func (c *Core) BarrierRekeyUpdate(ctx context.Context, key []byte, nonce string) return nil, nil } - // Recover the master key or recovery key + // Recover the root key or recovery key var recoveredKey []byte if existingConfig.SecretThreshold == 1 { recoveredKey = c.barrierRekeyConfig.RekeyProgress[0] @@ -387,7 +387,7 @@ func (c *Core) BarrierRekeyUpdate(ctx context.Context, key []byte, nonce string) recoveredKey, err = shamir.Combine(c.barrierRekeyConfig.RekeyProgress) c.barrierRekeyConfig.RekeyProgress = nil if err != nil { - return nil, logical.CodedError(http.StatusInternalServerError, errwrap.Wrapf("failed to compute master key: {{err}}", err).Error()) + return nil, logical.CodedError(http.StatusInternalServerError, errwrap.Wrapf("failed to compute root key: {{err}}", err).Error()) } } @@ -398,7 +398,7 @@ func (c *Core) BarrierRekeyUpdate(ctx context.Context, key []byte, nonce string) return nil, logical.CodedError(http.StatusBadRequest, errwrap.Wrapf("recovery key verification failed: {{err}}", err).Error()) } case c.seal.BarrierType() == wrapping.Shamir: - if c.seal.StoredKeysSupported() == seal.StoredKeysSupportedShamirMaster { + if c.seal.StoredKeysSupported() == seal.StoredKeysSupportedShamirRoot { testseal := NewDefaultSeal(&seal.Access{ Wrapper: aeadwrapper.NewShamirWrapper(&wrapping.WrapperOptions{ Logger: c.logger.Named("testseal"), @@ -416,23 +416,23 @@ func (c *Core) BarrierRekeyUpdate(ctx context.Context, key []byte, nonce string) testseal.SetCachedBarrierConfig(cfg) stored, err := testseal.GetStoredKeys(ctx) if err != nil { - return nil, logical.CodedError(http.StatusInternalServerError, errwrap.Wrapf("failed to read master key: {{err}}", err).Error()) + return nil, logical.CodedError(http.StatusInternalServerError, errwrap.Wrapf("failed to read root key: {{err}}", err).Error()) } recoveredKey = stored[0] } - if err := c.barrier.VerifyMaster(recoveredKey); err != nil { - c.logger.Error("master key verification failed", "error", err) - return nil, logical.CodedError(http.StatusBadRequest, errwrap.Wrapf("master key verification failed: {{err}}", err).Error()) + if err := c.barrier.VerifyRoot(recoveredKey); err != nil { + c.logger.Error("root key verification failed", "error", err) + return nil, logical.CodedError(http.StatusBadRequest, errwrap.Wrapf("root key verification failed: {{err}}", 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 - // new master key. + // new root key. newKey, err := c.barrier.GenerateKey(c.secureRandomReader) if err != nil { - c.logger.Error("failed to generate master key", "error", err) - return nil, logical.CodedError(http.StatusInternalServerError, errwrap.Wrapf("master key generation failed: {{err}}", err).Error()) + c.logger.Error("failed to generate root key", "error", err) + return nil, logical.CodedError(http.StatusInternalServerError, errwrap.Wrapf("root key generation failed: {{err}}", err).Error()) } results := &RekeyResult{ @@ -539,17 +539,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 { return logical.CodedError(http.StatusInternalServerError, errwrap.Wrapf("failed to perform rekey: {{err}}", 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) return logical.CodedError(http.StatusInternalServerError, errwrap.Wrapf("failed to store keys: {{err}}", err).Error()) } // 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) return logical.CodedError(http.StatusInternalServerError, errwrap.Wrapf("failed to rekey barrier: {{err}}", err).Error()) } @@ -656,7 +656,7 @@ func (c *Core) RecoveryRekeyUpdate(ctx context.Context, key []byte, nonce string return nil, nil } - // Recover the master key + // Recover the root key var recoveryKey []byte if existingConfig.SecretThreshold == 1 { recoveryKey = c.recoveryRekeyConfig.RekeyProgress[0] @@ -675,23 +675,23 @@ func (c *Core) RecoveryRekeyUpdate(ctx context.Context, key []byte, nonce string return nil, logical.CodedError(http.StatusBadRequest, errwrap.Wrapf("recovery key verification failed: {{err}}", err).Error()) } - // Generate a new master key - newMasterKey, err := c.barrier.GenerateKey(c.secureRandomReader) + // Generate a new root key + newRootKey, err := c.barrier.GenerateKey(c.secureRandomReader) if err != nil { c.logger.Error("failed to generate recovery key", "error", err) return nil, logical.CodedError(http.StatusInternalServerError, errwrap.Wrapf("recovery key generation failed: {{err}}", 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{ Backup: c.recoveryRekeyConfig.Backup, } if c.recoveryRekeyConfig.SecretShares == 1 { - results.SecretShares = append(results.SecretShares, newMasterKey) + results.SecretShares = append(results.SecretShares, newRootKey) } else { - // Split the master key using the Shamir algorithm - shares, err := shamir.Split(newMasterKey, c.recoveryRekeyConfig.SecretShares, c.recoveryRekeyConfig.SecretThreshold) + // Split the root key using the Shamir algorithm + shares, err := shamir.Split(newRootKey, c.recoveryRekeyConfig.SecretShares, c.recoveryRekeyConfig.SecretThreshold) if err != nil { c.logger.Error("failed to generate shares", "error", err) return nil, logical.CodedError(http.StatusInternalServerError, errwrap.Wrapf("failed to generate shares: {{err}}", err).Error()) @@ -749,14 +749,14 @@ func (c *Core) RecoveryRekeyUpdate(ctx context.Context, key []byte, nonce string return nil, logical.CodedError(http.StatusInternalServerError, errwrap.Wrapf("failed to generate verification nonce: {{err}}", err).Error()) } c.recoveryRekeyConfig.VerificationNonce = nonce - c.recoveryRekeyConfig.VerificationKey = newMasterKey + c.recoveryRekeyConfig.VerificationKey = newRootKey results.VerificationRequired = true results.VerificationNonce = nonce return results, nil } - if err := c.performRecoveryRekey(ctx, newMasterKey); err != nil { + if err := c.performRecoveryRekey(ctx, newRootKey); err != nil { return nil, logical.CodedError(http.StatusInternalServerError, errwrap.Wrapf("failed to perform recovery rekey: {{err}}", err).Error()) } @@ -764,8 +764,8 @@ func (c *Core) RecoveryRekeyUpdate(ctx context.Context, key []byte, nonce string return results, nil } -func (c *Core) performRecoveryRekey(ctx context.Context, newMasterKey []byte) logical.HTTPCodedError { - if err := c.seal.SetRecoveryKey(ctx, newMasterKey); err != nil { +func (c *Core) performRecoveryRekey(ctx context.Context, newRootKey []byte) logical.HTTPCodedError { + if err := c.seal.SetRecoveryKey(ctx, newRootKey); err != nil { c.logger.Error("failed to set recovery key", "error", err) return logical.CodedError(http.StatusInternalServerError, errwrap.Wrapf("failed to set recovery key: {{err}}", err).Error()) } @@ -868,7 +868,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 if config.SecretThreshold == 1 { recoveredKey = config.VerificationProgress[0] diff --git a/vault/seal.go b/vault/seal.go index 6697f15123d4..4b81a401ea8d 100644 --- a/vault/seal.go +++ b/vault/seal.go @@ -22,7 +22,7 @@ const ( // 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 // 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" // recoverySealConfigPath is the path to the recovery key seal @@ -138,7 +138,7 @@ func (d *defaultSeal) StoredKeysSupported() seal.StoredKeysSupport { case isLegacy: return seal.StoredKeysNotSupported default: - return seal.StoredKeysSupportedShamirMaster + return seal.StoredKeysSupportedShamirRoot } } diff --git a/vault/seal/seal.go b/vault/seal/seal.go index 0df1cf0bf417..36e081f0846a 100644 --- a/vault/seal/seal.go +++ b/vault/seal/seal.go @@ -15,7 +15,7 @@ const ( StoredKeysInvalid StoredKeysSupport = iota StoredKeysNotSupported StoredKeysSupportedGeneric - StoredKeysSupportedShamirMaster + StoredKeysSupportedShamirRoot ) func (s StoredKeysSupport) String() string { @@ -24,7 +24,7 @@ func (s StoredKeysSupport) String() string { return "Old-style Shamir" case StoredKeysSupportedGeneric: return "AutoUnseal" - case StoredKeysSupportedShamirMaster: + case StoredKeysSupportedShamirRoot: return "New-style Shamir" default: return "Invalid StoredKeys type" diff --git a/vault/seal_testing.go b/vault/seal_testing.go index 5c1baccb4059..982b44a3434b 100644 --- a/vault/seal_testing.go +++ b/vault/seal_testing.go @@ -12,7 +12,7 @@ func TestCoreUnsealedWithConfigs(t testing.T, barrierConf, recoveryConf *SealCon t.Helper() opts := &seal.TestSealOpts{} if recoveryConf == nil { - opts.StoredKeys = seal.StoredKeysSupportedShamirMaster + opts.StoredKeys = seal.StoredKeysSupportedShamirRoot } return TestCoreUnsealedWithConfigSealOpts(t, barrierConf, recoveryConf, opts) } diff --git a/vault/seal_testing_util.go b/vault/seal_testing_util.go index b5379f3ae672..193ec62dd92b 100644 --- a/vault/seal_testing_util.go +++ b/vault/seal_testing_util.go @@ -19,7 +19,7 @@ func NewTestSeal(t testing.T, opts *seal.TestSealOpts) Seal { } switch opts.StoredKeys { - case seal.StoredKeysSupportedShamirMaster: + case seal.StoredKeysSupportedShamirRoot: newSeal := NewDefaultSeal(&seal.Access{ Wrapper: aeadwrapper.NewShamirWrapper(&wrapping.WrapperOptions{ Logger: opts.Logger, From 25b55813062c99ab0371142e44d6d72d4926b11e Mon Sep 17 00:00:00 2001 From: Jim Kalafut Date: Mon, 6 Dec 2021 15:55:32 -0800 Subject: [PATCH 2/5] Restore accidentally deleted line --- vault/barrier.go | 1 + 1 file changed, 1 insertion(+) diff --git a/vault/barrier.go b/vault/barrier.go index 66b4a126ea4b..a9b4ab9ae4df 100644 --- a/vault/barrier.go +++ b/vault/barrier.go @@ -142,6 +142,7 @@ type SecurityBarrier interface { // SetRotationConfig updates the auto-rotation config for the barrier key SetRotationConfig(ctx context.Context, config KeyRotationConfig) error + // Rekey is used to change the master key used to protect the keyring Rekey(context.Context, []byte) error // For replication we must send over the keyring, so this must be available From f3eb5c0fcdc26c27e76589763883f1b2723f1435 Mon Sep 17 00:00:00 2001 From: Jim Kalafut Date: Mon, 6 Dec 2021 16:15:58 -0800 Subject: [PATCH 3/5] Add changelog --- changelog/13324.txt | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 changelog/13324.txt diff --git a/changelog/13324.txt b/changelog/13324.txt new file mode 100644 index 000000000000..f0bced301614 --- /dev/null +++ b/changelog/13324.txt @@ -0,0 +1,3 @@ +```release-note:improvement +core: Replace "master key" terminology with "root key" +``` From 2bdd7ba27708182643931c522f49c537396a19d5 Mon Sep 17 00:00:00 2001 From: Jim Kalafut Date: Mon, 6 Dec 2021 16:20:58 -0800 Subject: [PATCH 4/5] Update root->recovery --- vault/rekey.go | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/vault/rekey.go b/vault/rekey.go index a7494038d4f1..9ee4c466337d 100644 --- a/vault/rekey.go +++ b/vault/rekey.go @@ -675,7 +675,7 @@ func (c *Core) RecoveryRekeyUpdate(ctx context.Context, key []byte, nonce string } // Generate a new root key - newRootKey, err := c.barrier.GenerateKey(c.secureRandomReader) + newRecoveryKey, err := c.barrier.GenerateKey(c.secureRandomReader) if err != nil { 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()) @@ -687,10 +687,10 @@ func (c *Core) RecoveryRekeyUpdate(ctx context.Context, key []byte, nonce string } if c.recoveryRekeyConfig.SecretShares == 1 { - results.SecretShares = append(results.SecretShares, newRootKey) + results.SecretShares = append(results.SecretShares, newRecoveryKey) } else { // Split the root key using the Shamir algorithm - shares, err := shamir.Split(newRootKey, c.recoveryRekeyConfig.SecretShares, c.recoveryRekeyConfig.SecretThreshold) + shares, err := shamir.Split(newRecoveryKey, c.recoveryRekeyConfig.SecretShares, c.recoveryRekeyConfig.SecretThreshold) if err != nil { c.logger.Error("failed to generate shares", "error", err) 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()) } c.recoveryRekeyConfig.VerificationNonce = nonce - c.recoveryRekeyConfig.VerificationKey = newRootKey + c.recoveryRekeyConfig.VerificationKey = newRecoveryKey results.VerificationRequired = true results.VerificationNonce = nonce return results, nil } - if err := c.performRecoveryRekey(ctx, newRootKey); 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()) } From 74f251a4d74396caa4b73837f5cc3e51bff52196 Mon Sep 17 00:00:00 2001 From: Jim Kalafut Date: Mon, 6 Dec 2021 16:49:26 -0800 Subject: [PATCH 5/5] Fix test --- vault/barrier_test.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/vault/barrier_test.go b/vault/barrier_test.go index ee9ea6e4d166..2c66fe748f87 100644 --- a/vault/barrier_test.go +++ b/vault/barrier_test.go @@ -245,8 +245,8 @@ func testInitAndUnseal(t *testing.T, b SecurityBarrier) (error, *logical.Storage t.Fatalf("should be unsealed") } - // Verify the master key - if err := b.VerifyMaster(key); err != nil { + // Verify the root key + if err := b.VerifyRoot(key); err != nil { t.Fatalf("err: %v", err) } return err, e, key