diff --git a/packages/snaps-controllers/src/snaps/SnapController.test.tsx b/packages/snaps-controllers/src/snaps/SnapController.test.tsx index 14a12f19d2..6d9214743a 100644 --- a/packages/snaps-controllers/src/snaps/SnapController.test.tsx +++ b/packages/snaps-controllers/src/snaps/SnapController.test.tsx @@ -78,6 +78,7 @@ import { getSnapControllerOptions, getSnapControllerWithEES, getSnapControllerWithEESOptions, + LEGACY_ENCRYPTION_KEY_DERIVATION_OPTIONS, loopbackDetect, LoopbackLocation, MOCK_BLOCK_NUMBER, @@ -8178,6 +8179,42 @@ describe('SnapController', () => { snapController.destroy(); }); + it('uses legacy decryption where needed', async () => { + const messenger = getSnapControllerMessenger(); + + const state = { foo: 'bar' }; + + const { data, iv, salt } = JSON.parse( + await encrypt( + ENCRYPTION_KEY, + state, + undefined, + undefined, + LEGACY_ENCRYPTION_KEY_DERIVATION_OPTIONS, + ), + ); + + const snapController = getSnapController( + getSnapControllerOptions({ + messenger, + state: { + snaps: { + [MOCK_SNAP_ID]: getPersistedSnapObject(), + }, + snapStates: { + [MOCK_SNAP_ID]: JSON.stringify({ data, iv, salt }), + }, + }, + }), + ); + + expect( + await messenger.call('SnapController:getSnapState', MOCK_SNAP_ID, true), + ).toStrictEqual(state); + + snapController.destroy(); + }); + it('throws an error if the state is corrupt', async () => { const messenger = getSnapControllerMessenger(); diff --git a/packages/snaps-controllers/src/snaps/SnapController.ts b/packages/snaps-controllers/src/snaps/SnapController.ts index 7637696eae..6bc0bee16b 100644 --- a/packages/snaps-controllers/src/snaps/SnapController.ts +++ b/packages/snaps-controllers/src/snaps/SnapController.ts @@ -1676,7 +1676,14 @@ export class SnapController extends BaseController< snapId, salt, useCache, - keyMetadata, + // When decrypting state we expect key metadata to be present. + // If it isn't present, we assume that the Snap state we are decrypting is old enough to use the legacy encryption params. + keyMetadata: keyMetadata ?? { + algorithm: 'PBKDF2', + params: { + iterations: 10_000, + }, + }, }); const decryptedState = await this.#encryptor.decryptWithKey(key, parsed);