-
-
Notifications
You must be signed in to change notification settings - Fork 230
feat: persist UserStorage e2e content keys using an encrypted keyStore #5129
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
New dependencies detected. Learn more about Socket for GitHub ↗︎
|
be2f7ca
to
62a9880
Compare
storeWrappedKey: (keyRef: string, wrappedKey: string): Promise<void> => { | ||
return new Promise((resolve) => { | ||
this.update((state) => { | ||
state.encryptedContentKeys[keyRef] = wrappedKey; | ||
resolve(); | ||
}); | ||
}); | ||
}, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do these need to be promises?
If we do want to make then pseudo promises, we can make the functions async and avoid return explicit promises.
// By using the `async` function syntax, the return type will be inferred as a promise.
storeWrappedKey: async (...): Promise<void> => {
this.update(...)
}
packages/profile-sync-controller/src/controllers/user-storage/UserStorageController.ts
Show resolved
Hide resolved
@@ -54,12 +56,14 @@ class EncryptorDecryptor { | |||
plaintext: string, | |||
password: string, | |||
nativeScryptCrypto?: NativeScrypt, | |||
keyStore?: KeyStore, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
long term (far future) - I don't really like how many layers we have to drill in this context (both for NativeScrypt, and for this).
We can think of some diff approach later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Coming back to this, lets see if it is worth exposing an interface to persist keys.
But maybe persisting will not be necessary in this approach that uses ECIES and does not use an expensive KDF.
const keyRef = `${hashedPassword}${bytesToHex(newSalt)}`; | ||
if (keyStore) { | ||
try { | ||
const storedKey = await keyStore.loadKey(keyRef); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oooh very cool, so this keyStore will be used to store the encrypted keys to be used by other potential platforms?
As we persist this on the extension, would we need a way for this to be accessible outside of the extension? Reason I'm asking is could we place this keystore into the snap storage? That way sites can access this from the snap rather than the extension?
nonce: bytesToBase64(nonce), | ||
ephemPublicKey: bytesToBase64(ephemeralPublic), | ||
ciphertext: bytesToBase64(encryptedMessage), | ||
} as Eip1024EncryptedData; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What fields are missing for this to be be type asserted?
…ing the app (#13803) ## **Description** There is serious performance impact of loading notifications on startup. It is roughly a 2 second lag, and the app freezes during this process. This is due to us processing the encryption key to be used for decrypting entries in UserStorage. This persists the a cached encryption key using existing storage mechanisms to securely store this hashed key. **NOTE:** This fix is an interim solution until we add e2e content keys for encryption (CC @mathieuartu @mirceanis) MetaMask/core#5129 ## **Related issues** Fixes: ## **Manual testing steps** 1. Enable Notifications 2. Close the app 3. Open the app and unlock the wallet EXPECTED - you should not see any lag or app freezing. ## **Screenshots/Recordings** <!-- If applicable, add screenshots and/or recordings to visualize the before and after of your change. --> ### **Before** https://www.loom.com/share/8951a714b9b34f79a3e988ed50f9f656?sid=ad2ff732-c893-49d6-bd4b-e7f13a3a08b5 <!-- [screenshots/recordings] --> ### **After** https://www.loom.com/share/fe0afadcd49b46bbbafe219f95777fb6?sid=ca0df6aa-b5c5-4ffd-a5ee-bc811f0f1058 <!-- [screenshots/recordings] --> ## **Pre-merge author checklist** - [x] I’ve followed [MetaMask Contributor Docs](https://github.com/MetaMask/contributor-docs) and [MetaMask Mobile Coding Standards](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/CODING_GUIDELINES.md). - [x] I've completed the PR template to the best of my ability - [x] I’ve included tests if applicable - [x] I’ve documented my code using [JSDoc](https://jsdoc.app/) format if applicable - [x] I’ve applied the right labels on the PR (see [labeling guidelines](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/LABELING_GUIDELINES.md)). Not required for external contributors. ## **Pre-merge reviewer checklist** - [ ] I've manually tested the PR (e.g. pull and build branch, run the app, test code being changed). - [ ] I confirm that this PR addresses all acceptance criteria described in the ticket it closes and includes the necessary testing evidence such as recordings and or screenshots.
… opening the app (#13803) ## **Description** There is serious performance impact of loading notifications on startup. It is roughly a 2 second lag, and the app freezes during this process. This is due to us processing the encryption key to be used for decrypting entries in UserStorage. This persists the a cached encryption key using existing storage mechanisms to securely store this hashed key. **NOTE:** This fix is an interim solution until we add e2e content keys for encryption (CC @mathieuartu @mirceanis) MetaMask/core#5129 ## **Related issues** Fixes: ## **Manual testing steps** 1. Enable Notifications 2. Close the app 3. Open the app and unlock the wallet EXPECTED - you should not see any lag or app freezing. ## **Screenshots/Recordings** <!-- If applicable, add screenshots and/or recordings to visualize the before and after of your change. --> ### **Before** https://www.loom.com/share/8951a714b9b34f79a3e988ed50f9f656?sid=ad2ff732-c893-49d6-bd4b-e7f13a3a08b5 <!-- [screenshots/recordings] --> ### **After** https://www.loom.com/share/fe0afadcd49b46bbbafe219f95777fb6?sid=ca0df6aa-b5c5-4ffd-a5ee-bc811f0f1058 <!-- [screenshots/recordings] --> ## **Pre-merge author checklist** - [x] I’ve followed [MetaMask Contributor Docs](https://github.com/MetaMask/contributor-docs) and [MetaMask Mobile Coding Standards](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/CODING_GUIDELINES.md). - [x] I've completed the PR template to the best of my ability - [x] I’ve included tests if applicable - [x] I’ve documented my code using [JSDoc](https://jsdoc.app/) format if applicable - [x] I’ve applied the right labels on the PR (see [labeling guidelines](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/LABELING_GUIDELINES.md)). Not required for external contributors. ## **Pre-merge reviewer checklist** - [ ] I've manually tested the PR (e.g. pull and build branch, run the app, test code being changed). - [ ] I confirm that this PR addresses all acceptance criteria described in the ticket it closes and includes the necessary testing evidence such as recordings and or screenshots.
… opening the app (#13803) ## **Description** There is serious performance impact of loading notifications on startup. It is roughly a 2 second lag, and the app freezes during this process. This is due to us processing the encryption key to be used for decrypting entries in UserStorage. This persists the a cached encryption key using existing storage mechanisms to securely store this hashed key. **NOTE:** This fix is an interim solution until we add e2e content keys for encryption (CC @mathieuartu @mirceanis) MetaMask/core#5129 ## **Related issues** Fixes: ## **Manual testing steps** 1. Enable Notifications 2. Close the app 3. Open the app and unlock the wallet EXPECTED - you should not see any lag or app freezing. ## **Screenshots/Recordings** <!-- If applicable, add screenshots and/or recordings to visualize the before and after of your change. --> ### **Before** https://www.loom.com/share/8951a714b9b34f79a3e988ed50f9f656?sid=ad2ff732-c893-49d6-bd4b-e7f13a3a08b5 <!-- [screenshots/recordings] --> ### **After** https://www.loom.com/share/fe0afadcd49b46bbbafe219f95777fb6?sid=ca0df6aa-b5c5-4ffd-a5ee-bc811f0f1058 <!-- [screenshots/recordings] --> ## **Pre-merge author checklist** - [x] I’ve followed [MetaMask Contributor Docs](https://github.com/MetaMask/contributor-docs) and [MetaMask Mobile Coding Standards](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/CODING_GUIDELINES.md). - [x] I've completed the PR template to the best of my ability - [x] I’ve included tests if applicable - [x] I’ve documented my code using [JSDoc](https://jsdoc.app/) format if applicable - [x] I’ve applied the right labels on the PR (see [labeling guidelines](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/LABELING_GUIDELINES.md)). Not required for external contributors. ## **Pre-merge reviewer checklist** - [ ] I've manually tested the PR (e.g. pull and build branch, run the app, test code being changed). - [ ] I confirm that this PR addresses all acceptance criteria described in the ticket it closes and includes the necessary testing evidence such as recordings and or screenshots.
…fications loading when opening the app (#13803) ## **Description** There is serious performance impact of loading notifications on startup. It is roughly a 2 second lag, and the app freezes during this process. This is due to us processing the encryption key to be used for decrypting entries in UserStorage. This persists the a cached encryption key using existing storage mechanisms to securely store this hashed key. **NOTE:** This fix is an interim solution until we add e2e content keys for encryption (CC @mathieuartu @mirceanis) MetaMask/core#5129 ## **Related issues** Fixes: ## **Manual testing steps** 1. Enable Notifications 2. Close the app 3. Open the app and unlock the wallet EXPECTED - you should not see any lag or app freezing. ## **Screenshots/Recordings** <!-- If applicable, add screenshots and/or recordings to visualize the before and after of your change. --> ### **Before** https://www.loom.com/share/8951a714b9b34f79a3e988ed50f9f656?sid=ad2ff732-c893-49d6-bd4b-e7f13a3a08b5 <!-- [screenshots/recordings] --> ### **After** https://www.loom.com/share/fe0afadcd49b46bbbafe219f95777fb6?sid=ca0df6aa-b5c5-4ffd-a5ee-bc811f0f1058 <!-- [screenshots/recordings] --> ## **Pre-merge author checklist** - [x] I’ve followed [MetaMask Contributor Docs](https://github.com/MetaMask/contributor-docs) and [MetaMask Mobile Coding Standards](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/CODING_GUIDELINES.md). - [x] I've completed the PR template to the best of my ability - [x] I’ve included tests if applicable - [x] I’ve documented my code using [JSDoc](https://jsdoc.app/) format if applicable - [x] I’ve applied the right labels on the PR (see [labeling guidelines](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/LABELING_GUIDELINES.md)). Not required for external contributors. ## **Pre-merge reviewer checklist** - [ ] I've manually tested the PR (e.g. pull and build branch, run the app, test code being changed). - [ ] I confirm that this PR addresses all acceptance criteria described in the ticket it closes and includes the necessary testing evidence such as recordings and or screenshots.
…fications loading when opening the app (#13811) - fix: cp-7.42.0 improve performance of notifications loading when opening the app (#13803) ## **Description** There is serious performance impact of loading notifications on startup. It is roughly a 2 second lag, and the app freezes during this process. This is due to us processing the encryption key to be used for decrypting entries in UserStorage. This persists the a cached encryption key using existing storage mechanisms to securely store this hashed key. **NOTE:** This fix is an interim solution until we add e2e content keys for encryption (CC @mathieuartu @mirceanis) MetaMask/core#5129 ## **Related issues** Fixes: ## **Manual testing steps** 1. Enable Notifications 2. Close the app 3. Open the app and unlock the wallet EXPECTED - you should not see any lag or app freezing. ## **Screenshots/Recordings** <!-- If applicable, add screenshots and/or recordings to visualize the before and after of your change. --> ### **Before** https://www.loom.com/share/8951a714b9b34f79a3e988ed50f9f656?sid=ad2ff732-c893-49d6-bd4b-e7f13a3a08b5 <!-- [screenshots/recordings] --> ### **After** https://www.loom.com/share/fe0afadcd49b46bbbafe219f95777fb6?sid=ca0df6aa-b5c5-4ffd-a5ee-bc811f0f1058 <!-- [screenshots/recordings] --> ## **Pre-merge author checklist** - [x] I’ve followed [MetaMask Contributor Docs](https://github.com/MetaMask/contributor-docs) and [MetaMask Mobile Coding Standards](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/CODING_GUIDELINES.md). - [x] I've completed the PR template to the best of my ability - [x] I’ve included tests if applicable - [x] I’ve documented my code using [JSDoc](https://jsdoc.app/) format if applicable - [x] I’ve applied the right labels on the PR (see [labeling guidelines](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/LABELING_GUIDELINES.md)). Not required for external contributors. ## **Pre-merge reviewer checklist** - [ ] I've manually tested the PR (e.g. pull and build branch, run the app, test code being changed). - [ ] I confirm that this PR addresses all acceptance criteria described in the ticket it closes and includes the necessary testing evidence such as recordings and or screenshots. [18f84aa](18f84aa) Co-authored-by: Prithpal Sooriya <[email protected]>
…ing the app (#13803) There is serious performance impact of loading notifications on startup. It is roughly a 2 second lag, and the app freezes during this process. This is due to us processing the encryption key to be used for decrypting entries in UserStorage. This persists the a cached encryption key using existing storage mechanisms to securely store this hashed key. **NOTE:** This fix is an interim solution until we add e2e content keys for encryption (CC @mathieuartu @mirceanis) MetaMask/core#5129 Fixes: 1. Enable Notifications 2. Close the app 3. Open the app and unlock the wallet EXPECTED - you should not see any lag or app freezing. <!-- If applicable, add screenshots and/or recordings to visualize the before and after of your change. --> https://www.loom.com/share/8951a714b9b34f79a3e988ed50f9f656?sid=ad2ff732-c893-49d6-bd4b-e7f13a3a08b5 <!-- [screenshots/recordings] --> https://www.loom.com/share/fe0afadcd49b46bbbafe219f95777fb6?sid=ca0df6aa-b5c5-4ffd-a5ee-bc811f0f1058 <!-- [screenshots/recordings] --> - [x] I’ve followed [MetaMask Contributor Docs](https://github.com/MetaMask/contributor-docs) and [MetaMask Mobile Coding Standards](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/CODING_GUIDELINES.md). - [x] I've completed the PR template to the best of my ability - [x] I’ve included tests if applicable - [x] I’ve documented my code using [JSDoc](https://jsdoc.app/) format if applicable - [x] I’ve applied the right labels on the PR (see [labeling guidelines](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/LABELING_GUIDELINES.md)). Not required for external contributors. - [ ] I've manually tested the PR (e.g. pull and build branch, run the app, test code being changed). - [ ] I confirm that this PR addresses all acceptance criteria described in the ticket it closes and includes the necessary testing evidence such as recordings and or screenshots. Modify better mocks Adjust jsdoc Adjust codeowner file Fix initModularizedControllers unit tests Remove log Add TransactionControllerInit function Add missing test cases Add missing event to NFT Controller Use template for controllerMessenger in test utils Use buildControllerInitRequestMock in notification controller unit tests Use callbacks as standadolone functions in transaction-controller-init Cleanup unnecessary events from transaction-controller-messenger Add back ControllerMessengerByControllerName Rename getCurrentChainId to getGlobalChainId Rename getUIState Alphabetical order of request Revert back deleted test Fix tests of utils Remove unused import Revert lint changes
Explanation
The
UserStorageController
e2e encryption keys are derived from astorageKey
that is specific to the user profile. The key derivation function used isscrypt
, with parameters recommended for password inputs. This means that it's a very costly operation (on the order of seconds on a 2024 mobile device).These derived keys are cached in memory for the lifetime of the controller instance, but a better approach would be to use a Key Store, to persist the derived keys in a safe manner. This would avoid the rerun of the costly key derivation operation on every app restart.
This set of changes also comes at a time when we're preparing for a multi-device/multi-srp user profile, so the implementation of the KeyStore relies on the new encryption capabilities of the message-signing-snap. The snap is already used for auth and is a key component of the UserStorageController, but we are introducing some defaults here that create even more coupling between the controller and the snap.
The proposed KeyStore implementation relies on the persistable state properties and the messagingSystem available to MM controllers, so externalizing this would create some overhead, but feedback is very welcome about the approach.
References
fixes #5128
Changelog
@metamask/profile-sync-controller
Checklist