54
54
// ErrEncKeyNotFound specifies that there was no encryption key found
55
55
// even if one was expected to be generated.
56
56
ErrEncKeyNotFound = fmt .Errorf ("macaroon encryption key not found" )
57
+
58
+ // ErrDefaultRootKeyNotFound is returned when the default root key is
59
+ // not found in the DB when it is expected to be.
60
+ ErrDefaultRootKeyNotFound = fmt .Errorf ("default root key not found" )
57
61
)
58
62
59
63
// RootKeyStorage implements the bakery.RootKeyStorage interface.
@@ -140,8 +144,8 @@ func (r *RootKeyStorage) CreateUnlock(password *[]byte) error {
140
144
}, func () {})
141
145
}
142
146
143
- // ChangePassword decrypts the macaroon root key with the old password and then
144
- // encrypts it again with the new password.
147
+ // ChangePassword decrypts all the macaroon root keys with the old password and
148
+ // then encrypts them again with the new password.
145
149
func (r * RootKeyStorage ) ChangePassword (oldPw , newPw []byte ) error {
146
150
// We need the store to already be unlocked. With this we can make sure
147
151
// that there already is a key in the DB.
@@ -159,19 +163,18 @@ func (r *RootKeyStorage) ChangePassword(oldPw, newPw []byte) error {
159
163
if bucket == nil {
160
164
return ErrRootKeyBucketNotFound
161
165
}
162
- encKeyDb := bucket .Get (encryptionKeyID )
163
- rootKeyDb := bucket .Get (DefaultRootKeyID )
164
166
165
- // Both the encryption key and the root key must be present
166
- // otherwise we are in the wrong state to change the password.
167
- if len (encKeyDb ) == 0 || len (rootKeyDb ) == 0 {
167
+ // The encryption key must be present, otherwise we are in the
168
+ // wrong state to change the password.
169
+ encKeyDB := bucket .Get (encryptionKeyID )
170
+ if len (encKeyDB ) == 0 {
168
171
return ErrEncKeyNotFound
169
172
}
170
173
171
174
// Unmarshal parameters for old encryption key and derive the
172
175
// old key with them.
173
176
encKeyOld := & snacl.SecretKey {}
174
- err := encKeyOld .Unmarshal (encKeyDb )
177
+ err := encKeyOld .Unmarshal (encKeyDB )
175
178
if err != nil {
176
179
return err
177
180
}
@@ -188,21 +191,42 @@ func (r *RootKeyStorage) ChangePassword(oldPw, newPw []byte) error {
188
191
return err
189
192
}
190
193
191
- // Now try to decrypt the root key with the old encryption key,
192
- // encrypt it with the new one and then store it in the DB.
193
- decryptedKey , err := encKeyOld .Decrypt (rootKeyDb )
194
- if err != nil {
195
- return err
196
- }
197
- rootKey := make ([]byte , len (decryptedKey ))
198
- copy (rootKey , decryptedKey )
199
- encryptedKey , err := encKeyNew .Encrypt (rootKey )
194
+ // foundDefaultRootKey is used to keep track of if we have
195
+ // found and re-encrypted the default root key so that we can
196
+ // return an error if it is not found.
197
+ var foundDefaultRootKey bool
198
+ err = bucket .ForEach (func (k , v []byte ) error {
199
+ // Skip the key if it is the encryption key ID since
200
+ // we do not want to re-encrypt this.
201
+ if bytes .Equal (k , encryptionKeyID ) {
202
+ return nil
203
+ }
204
+
205
+ if bytes .Equal (k , DefaultRootKeyID ) {
206
+ foundDefaultRootKey = true
207
+ }
208
+
209
+ // Now try to decrypt the root key with the old
210
+ // encryption key, encrypt it with the new one and then
211
+ // store it in the DB.
212
+ decryptedKey , err := encKeyOld .Decrypt (v )
213
+ if err != nil {
214
+ return err
215
+ }
216
+
217
+ encryptedKey , err := encKeyNew .Encrypt (decryptedKey )
218
+ if err != nil {
219
+ return err
220
+ }
221
+
222
+ return bucket .Put (k , encryptedKey )
223
+ })
200
224
if err != nil {
201
225
return err
202
226
}
203
- err = bucket . Put ( DefaultRootKeyID , encryptedKey )
204
- if err != nil {
205
- return err
227
+
228
+ if ! foundDefaultRootKey {
229
+ return ErrDefaultRootKeyNotFound
206
230
}
207
231
208
232
// Finally, store the new encryption key parameters in the DB
0 commit comments