1package vault 2 3import ( 4 "bytes" 5 "encoding/json" 6 "fmt" 7 "time" 8 9 "github.com/hashicorp/errwrap" 10 "github.com/hashicorp/vault/sdk/helper/jsonutil" 11) 12 13// Keyring is used to manage multiple encryption keys used by 14// the barrier. New keys can be installed and each has a sequential term. 15// The term used to encrypt a key is prefixed to the key written out. 16// All data is encrypted with the latest key, but storing the old keys 17// allows for decryption of keys written previously. Along with the encryption 18// keys, the keyring also tracks the master key. This is necessary so that 19// when a new key is added to the keyring, we can encrypt with the master key 20// and write out the new keyring. 21type Keyring struct { 22 masterKey []byte 23 keys map[uint32]*Key 24 activeTerm uint32 25} 26 27// EncodedKeyring is used for serialization of the keyring 28type EncodedKeyring struct { 29 MasterKey []byte 30 Keys []*Key 31} 32 33// Key represents a single term, along with the key used. 34type Key struct { 35 Term uint32 36 Version int 37 Value []byte 38 InstallTime time.Time 39} 40 41// Serialize is used to create a byte encoded key 42func (k *Key) Serialize() ([]byte, error) { 43 return json.Marshal(k) 44} 45 46// DeserializeKey is used to deserialize and return a new key 47func DeserializeKey(buf []byte) (*Key, error) { 48 k := new(Key) 49 if err := jsonutil.DecodeJSON(buf, k); err != nil { 50 return nil, errwrap.Wrapf("deserialization failed: {{err}}", err) 51 } 52 return k, nil 53} 54 55// NewKeyring creates a new keyring 56func NewKeyring() *Keyring { 57 k := &Keyring{ 58 keys: make(map[uint32]*Key), 59 activeTerm: 0, 60 } 61 return k 62} 63 64// Clone returns a new copy of the keyring 65func (k *Keyring) Clone() *Keyring { 66 clone := &Keyring{ 67 masterKey: k.masterKey, 68 keys: make(map[uint32]*Key, len(k.keys)), 69 activeTerm: k.activeTerm, 70 } 71 for idx, key := range k.keys { 72 clone.keys[idx] = key 73 } 74 return clone 75} 76 77// AddKey adds a new key to the keyring 78func (k *Keyring) AddKey(key *Key) (*Keyring, error) { 79 // Ensure there is no conflict 80 if exist, ok := k.keys[key.Term]; ok { 81 if !bytes.Equal(key.Value, exist.Value) { 82 return nil, fmt.Errorf("conflicting key for term %d already installed", key.Term) 83 } 84 return k, nil 85 } 86 87 // Add a time if none 88 if key.InstallTime.IsZero() { 89 key.InstallTime = time.Now() 90 } 91 92 // Make a new keyring 93 clone := k.Clone() 94 95 // Install the new key 96 clone.keys[key.Term] = key 97 98 // Update the active term if newer 99 if key.Term > clone.activeTerm { 100 clone.activeTerm = key.Term 101 } 102 return clone, nil 103} 104 105// RemoveKey removes a key from the keyring 106func (k *Keyring) RemoveKey(term uint32) (*Keyring, error) { 107 // Ensure this is not the active key 108 if term == k.activeTerm { 109 return nil, fmt.Errorf("cannot remove active key") 110 } 111 112 // Check if this term does not exist 113 if _, ok := k.keys[term]; !ok { 114 return k, nil 115 } 116 117 // Delete the key 118 clone := k.Clone() 119 delete(clone.keys, term) 120 return clone, nil 121} 122 123// ActiveTerm returns the currently active term 124func (k *Keyring) ActiveTerm() uint32 { 125 return k.activeTerm 126} 127 128// ActiveKey returns the active encryption key, or nil 129func (k *Keyring) ActiveKey() *Key { 130 return k.keys[k.activeTerm] 131} 132 133// TermKey returns the key for the given term, or nil 134func (k *Keyring) TermKey(term uint32) *Key { 135 return k.keys[term] 136} 137 138// SetMasterKey is used to update the master key 139func (k *Keyring) SetMasterKey(val []byte) *Keyring { 140 valCopy := make([]byte, len(val)) 141 copy(valCopy, val) 142 clone := k.Clone() 143 clone.masterKey = valCopy 144 return clone 145} 146 147// MasterKey returns the master key 148func (k *Keyring) MasterKey() []byte { 149 return k.masterKey 150} 151 152// Serialize is used to create a byte encoded keyring 153func (k *Keyring) Serialize() ([]byte, error) { 154 // Create the encoded entry 155 enc := EncodedKeyring{ 156 MasterKey: k.masterKey, 157 } 158 for _, key := range k.keys { 159 enc.Keys = append(enc.Keys, key) 160 } 161 162 // JSON encode the keyring 163 buf, err := json.Marshal(enc) 164 return buf, err 165} 166 167// DeserializeKeyring is used to deserialize and return a new keyring 168func DeserializeKeyring(buf []byte) (*Keyring, error) { 169 // Deserialize the keyring 170 var enc EncodedKeyring 171 if err := jsonutil.DecodeJSON(buf, &enc); err != nil { 172 return nil, errwrap.Wrapf("deserialization failed: {{err}}", err) 173 } 174 175 // Create a new keyring 176 k := NewKeyring() 177 k.masterKey = enc.MasterKey 178 for _, key := range enc.Keys { 179 k.keys[key.Term] = key 180 if key.Term > k.activeTerm { 181 k.activeTerm = key.Term 182 } 183 } 184 return k, nil 185} 186 187// N.B.: 188// Since Go 1.5 these are not reliable; see the documentation around the memzero 189// function. These are best-effort. 190func (k *Keyring) Zeroize(keysToo bool) { 191 if k == nil { 192 return 193 } 194 if k.masterKey != nil { 195 memzero(k.masterKey) 196 } 197 if !keysToo || k.keys == nil { 198 return 199 } 200 for _, key := range k.keys { 201 memzero(key.Value) 202 } 203} 204