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