-
-
Notifications
You must be signed in to change notification settings - Fork 126
Add encryptor types
#293
Add encryptor types
#293
Conversation
src/KeyringController.ts
Outdated
| if (this.cacheEncryptionKey) { | ||
| assertIsKeyEncryptor(encryptor); | ||
| } |
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.
We can't cache the encryption key if the provided encryptor does not support it
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.
This takes inspiration from @metamask/keyring-controller: https://github.com/MetaMask/core/blob/main/packages/keyring-controller/tests/mocks/mockEncryptor.ts
6655146 to
848eb83
Compare
|
Would be nice if we can get out #290 before this is merged. |
| expect(initialMemStore.encryptionKey).toBeUndefined(); | ||
| expect(initialMemStore.encryptionSalt).toBeUndefined(); |
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.
These are not applicable anymore, as cacheEncryptionKey is set to true on construction (before the first createNewVaultAndKeychain > persistAllKeyrings is called), so encryptionKey and encryptionSalt will be already defined
960c02c to
aff13b0
Compare
Gudahtt
left a comment
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.
A few pending suggestions/questions but overall this LGTM!
src/KeyringController.ts
Outdated
| serializedKeyrings, | ||
| ); | ||
| vaultJSON.salt = encryptionSalt; | ||
| if (encryptionSalt) { |
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.
Nit: Hmm, this should always exist if encryptionKey exists. Maybe there's a way to make that more clear using types.
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.
I changed the KeyringControllerState type to:
export type KeyringControllerState = {
keyrings: KeyringObject[];
isUnlocked: boolean;
} & (
| { encryptionKey: string; encryptionSalt: string }
| {
encryptionKey?: never;
encryptionSalt?: never;
}
);Is there a better way to represent this?
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.
We could also enforce the right encryptor type doing something similar on KeyringControllerArgs:
export type KeyringControllerArgs = {
keyringBuilders?: { (): Keyring<Json>; type: string }[];
initState?: KeyringControllerPersistentState;
} & (
| { encryptor?: ExportableKeyEncryptor; cacheEncryptionKey: true }
| {
encryptor?: GenericEncryptor | ExportableKeyEncryptor;
cacheEncryptionKey: false;
}
);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.
Nice! Looks reasonable
| if ( | ||
| this.password && | ||
| this.#encryptor.updateVault && | ||
| (await this.#encryptor.updateVault(encryptedVault, this.password)) !== |
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.
Nit: most of the work this function is doing (the encryption) is being thrown away here. Maybe we can come back to this an optimize this by having it just check whether the vault is outdated or not instead (e.g. expose isVaultUpdated, or inline that logic here).
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.
Yes, that's quite bad. The best way would be to expose isVaultUpdated from browser-passworder, because I don't think there's a nice way to inline that logic here, as eth-keyring-controller would have to know the latest vault parameters (DEFAULT_DERIVATION_PARAMS in browser-passworder, which is also not exposed)
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.
Right, good point. Maybe something to address in a follow up PR then
mcmire
left a comment
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.
I had some nits as well, but this makes sense and looks good.
Co-authored-by: Elliot Winkler <elliot.winkler@gmail.com>
bb102b7 to
e3a3545
Compare
Gudahtt
left a comment
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.
LGTM!
Description
Currently
encryptortype isany, and as different clients can use different encryptor utilities, we need to establish a minimum supported (or needed) interface that the encryptor should implement.This PR adds some types and guards to the encryptor, taking into account
@metamask/browser-passworder, which is the encryptor used by the extension, and the Encryptor class used by mobileRestrictions have also been added for
cacheEncryptionKeyandencryptor, as the methods that the encryptor must support depends on whether we need the encryption key to be exported or not. To do this, public class variables have been substituted with sharp vars and a check on construction has been added: an error is thrown when they are incompatibleChanges
encryptorclass variable is now inaccessiblecacheEncryptionKeyclass variable is now inaccessibleencryptorconstructor option type has been changed toGenericEncryptor | ExportableKeyEncryptor | undefinedReferences
Waiting on MetaMask/browser-passworder#49
encryptorlacks sufficient typing #295Checklist