1package vault 2 3import ( 4 "context" 5 "errors" 6 "io" 7 "time" 8 9 "github.com/hashicorp/vault/sdk/logical" 10) 11 12var ( 13 // ErrBarrierSealed is returned if an operation is performed on 14 // a sealed barrier. No operation is expected to succeed before unsealing 15 ErrBarrierSealed = errors.New("Vault is sealed") 16 17 // ErrBarrierAlreadyInit is returned if the barrier is already 18 // initialized. This prevents a re-initialization. 19 ErrBarrierAlreadyInit = errors.New("Vault is already initialized") 20 21 // ErrBarrierNotInit is returned if a non-initialized barrier 22 // is attempted to be unsealed. 23 ErrBarrierNotInit = errors.New("Vault is not initialized") 24 25 // ErrBarrierInvalidKey is returned if the Unseal key is invalid 26 ErrBarrierInvalidKey = errors.New("Unseal failed, invalid key") 27) 28 29const ( 30 // barrierInitPath is the path used to store our init sentinel file 31 barrierInitPath = "barrier/init" 32 33 // keyringPath is the location of the keyring data. This is encrypted 34 // by the master key. 35 keyringPath = "core/keyring" 36 keyringPrefix = "core/" 37 38 // keyringUpgradePrefix is the path used to store keyring update entries. 39 // When running in HA mode, the active instance will install the new key 40 // and re-write the keyring. For standby instances, they need an upgrade 41 // path from key N to N+1. They cannot just use the master key because 42 // in the event of a rekey, that master key can no longer decrypt the keyring. 43 // When key N+1 is installed, we create an entry at "prefix/N" which uses 44 // encryption key N to provide the N+1 key. The standby instances scan 45 // for this periodically and refresh their keyring. The upgrade keys 46 // are deleted after a few minutes, but this provides enough time for the 47 // standby instances to upgrade without causing any disruption. 48 keyringUpgradePrefix = "core/upgrade/" 49 50 // masterKeyPath is the location of the master key. This is encrypted 51 // by the latest key in the keyring. This is only used by standby instances 52 // to handle the case of a rekey. If the active instance does a rekey, 53 // the standby instances can no longer reload the keyring since they 54 // have the old master key. This key can be decrypted if you have the 55 // keyring to discover the new master key. The new master key is then 56 // used to reload the keyring itself. 57 masterKeyPath = "core/master" 58 59 // shamirKekPath is used with Shamir in v1.3+ to store a copy of the 60 // unseal key behind the barrier. As with masterKeyPath this is primarily 61 // used by standbys to handle rekeys. It also comes into play when restoring 62 // raft snapshots. 63 shamirKekPath = "core/shamir-kek" 64) 65 66// SecurityBarrier is a critical component of Vault. It is used to wrap 67// an untrusted physical backend and provide a single point of encryption, 68// decryption and checksum verification. The goal is to ensure that any 69// data written to the barrier is confidential and that integrity is preserved. 70// As a real-world analogy, this is the steel and concrete wrapper around 71// a Vault. The barrier should only be Unlockable given its key. 72type SecurityBarrier interface { 73 // Initialized checks if the barrier has been initialized 74 // and has a master key set. 75 Initialized(ctx context.Context) (bool, error) 76 77 // Initialize works only if the barrier has not been initialized 78 // and makes use of the given master key. When sealKey is provided 79 // it's because we're using a new-style Shamir seal, and masterKey 80 // is to be stored using sealKey to encrypt it. 81 Initialize(ctx context.Context, masterKey []byte, sealKey []byte, random io.Reader) error 82 83 // GenerateKey is used to generate a new key 84 GenerateKey(io.Reader) ([]byte, error) 85 86 // KeyLength is used to sanity check a key 87 KeyLength() (int, int) 88 89 // Sealed checks if the barrier has been unlocked yet. The Barrier 90 // is not expected to be able to perform any CRUD until it is unsealed. 91 Sealed() (bool, error) 92 93 // Unseal is used to provide the master key which permits the barrier 94 // to be unsealed. If the key is not correct, the barrier remains sealed. 95 Unseal(ctx context.Context, key []byte) error 96 97 // VerifyMaster is used to check if the given key matches the master key 98 VerifyMaster(key []byte) error 99 100 // SetMasterKey is used to directly set a new master key. This is used in 101 // replicated scenarios due to the chicken and egg problem of reloading the 102 // keyring from disk before we have the master key to decrypt it. 103 SetMasterKey(key []byte) error 104 105 // ReloadKeyring is used to re-read the underlying keyring. 106 // This is used for HA deployments to ensure the latest keyring 107 // is present in the leader. 108 ReloadKeyring(ctx context.Context) error 109 110 // ReloadMasterKey is used to re-read the underlying masterkey. 111 // This is used for HA deployments to ensure the latest master key 112 // is available for keyring reloading. 113 ReloadMasterKey(ctx context.Context) error 114 115 // Seal is used to re-seal the barrier. This requires the barrier to 116 // be unsealed again to perform any further operations. 117 Seal() error 118 119 // Rotate is used to create a new encryption key. All future writes 120 // should use the new key, while old values should still be decryptable. 121 Rotate(ctx context.Context, reader io.Reader) (uint32, error) 122 123 // CreateUpgrade creates an upgrade path key to the given term from the previous term 124 CreateUpgrade(ctx context.Context, term uint32) error 125 126 // DestroyUpgrade destroys the upgrade path key to the given term 127 DestroyUpgrade(ctx context.Context, term uint32) error 128 129 // CheckUpgrade looks for an upgrade to the current term and installs it 130 CheckUpgrade(ctx context.Context) (bool, uint32, error) 131 132 // ActiveKeyInfo is used to inform details about the active key 133 ActiveKeyInfo() (*KeyInfo, error) 134 135 // Rekey is used to change the master key used to protect the keyring 136 Rekey(context.Context, []byte) error 137 138 // For replication we must send over the keyring, so this must be available 139 Keyring() (*Keyring, error) 140 141 // SecurityBarrier must provide the storage APIs 142 logical.Storage 143 144 // SecurityBarrier must provide the encryption APIs 145 BarrierEncryptor 146} 147 148// BarrierStorage is the storage only interface required for a Barrier. 149type BarrierStorage interface { 150 // Put is used to insert or update an entry 151 Put(ctx context.Context, entry *logical.StorageEntry) error 152 153 // Get is used to fetch an entry 154 Get(ctx context.Context, key string) (*logical.StorageEntry, error) 155 156 // Delete is used to permanently delete an entry 157 Delete(ctx context.Context, key string) error 158 159 // List is used ot list all the keys under a given 160 // prefix, up to the next prefix. 161 List(ctx context.Context, prefix string) ([]string, error) 162} 163 164// BarrierEncryptor is the in memory only interface that does not actually 165// use the underlying barrier. It is used for lower level modules like the 166// Write-Ahead-Log and Merkle index to allow them to use the barrier. 167type BarrierEncryptor interface { 168 Encrypt(ctx context.Context, key string, plaintext []byte) ([]byte, error) 169 Decrypt(ctx context.Context, key string, ciphertext []byte) ([]byte, error) 170} 171 172// KeyInfo is used to convey information about the encryption key 173type KeyInfo struct { 174 Term int 175 InstallTime time.Time 176} 177