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