Skip to content
This repository was archived by the owner on Oct 7, 2024. It is now read-only.

Add encryptor types - #293

Merged
mikesposito merged 17 commits into
mainfrom
refactor/add-encryptor-types
Nov 14, 2023
Merged

Add encryptor types#293
mikesposito merged 17 commits into
mainfrom
refactor/add-encryptor-types

Conversation

@mikesposito

@mikespositomikesposito commented Nov 7, 2023

Copy link
Copy Markdown
Member

Description

Currently encryptor type is any, 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 mobile

Restrictions have also been added for cacheEncryptionKey and encryptor, 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 incompatible

Changes

  • BREAKING: encryptor class variable is now inaccessible
  • BREAKING: cacheEncryptionKey class variable is now inaccessible
  • BREAKING: encryptor constructor option type has been changed to GenericEncryptor | ExportableKeyEncryptor | undefined

References

Waiting on MetaMask/browser-passworder#49

Checklist

  • I've updated the test suite for new or updated code as appropriate
  • I've updated documentation for new or updated code as appropriate (note: this will usually be JSDoc)
  • I've highlighted breaking changes using the "BREAKING" category above as appropriate

Comment threadsrc/KeyringController.ts Outdated
Comment threadsrc/KeyringController.ts Outdated
Comment on lines +945 to +947
if (this.cacheEncryptionKey) {
assertIsKeyEncryptor(encryptor);
}

Copy link
Copy Markdown
MemberAuthor

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

@mikesposito
mikesposito marked this pull request as ready for review November 10, 2023 10:40
@mikesposito
mikesposito requested a review from a team as a code ownerNovember 10, 2023 10:40

Copy link
Copy Markdown
MemberAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@mikesposito
mikespositoforce-pushed the refactor/add-encryptor-types branch 2 times, most recently from 6655146 to 848eb83CompareNovember 10, 2023 12:08
Comment threadsrc/KeyringController.ts Outdated
@legobeat

Copy link
Copy Markdown
Contributor

Would be nice if we can get out #290 before this is merged.

Comment on lines -392 to -332
expect(initialMemStore.encryptionKey).toBeUndefined();
expect(initialMemStore.encryptionSalt).toBeUndefined();

Copy link
Copy Markdown
MemberAuthor

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

@mikesposito
mikespositoforce-pushed the refactor/add-encryptor-types branch from 960c02c to aff13b0CompareNovember 13, 2023 14:13
Gudahtt
Gudahtt previously approved these changes Nov 13, 2023

@GudahttGudahtt left a comment

Copy link
Copy Markdown
Member

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!

Comment threadsrc/KeyringController.ts Outdated
serializedKeyrings,
);
vaultJSON.salt = encryptionSalt;
if (encryptionSalt) {

Copy link
Copy Markdown
Member

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.

@mikespositomikespositoNov 14, 2023

Copy link
Copy Markdown
MemberAuthor

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:

exporttypeKeyringControllerState={keyrings: KeyringObject[];isUnlocked: boolean;}&(|{encryptionKey: string;encryptionSalt: string}|{encryptionKey?: never;encryptionSalt?: never;});

Is there a better way to represent this?

Copy link
Copy Markdown
MemberAuthor

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:

exporttypeKeyringControllerArgs={keyringBuilders?: {(): Keyring<Json>;type: string}[];initState?: KeyringControllerPersistentState;}&(|{encryptor?: ExportableKeyEncryptor;cacheEncryptionKey: true}|{encryptor?: GenericEncryptor|ExportableKeyEncryptor;cacheEncryptionKey: false;});

Copy link
Copy Markdown
Member

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)) !==

Copy link
Copy Markdown
Member

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).

Copy link
Copy Markdown
MemberAuthor

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)

Copy link
Copy Markdown
Member

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

Comment threadsrc/KeyringController.test.ts Outdated
mcmire
mcmire previously approved these changes Nov 13, 2023

@mcmiremcmire left a comment

Copy link
Copy Markdown
Contributor

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.

Comment threadsrc/KeyringController.ts Outdated
Comment threadsrc/KeyringController.test.ts Outdated
Co-authored-by: Elliot Winkler <elliot.winkler@gmail.com>
@mikesposito
mikesposito dismissed stale reviews from mcmire and Gudahtt via 1de36a5November 14, 2023 09:21
@mikesposito
mikespositoforce-pushed the refactor/add-encryptor-types branch from bb102b7 to e3a3545CompareNovember 14, 2023 11:21

@GudahttGudahtt left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM!

@mikesposito
mikesposito merged commit 75b4893 into mainNov 14, 2023
@mikesposito
mikesposito deleted the refactor/add-encryptor-types branch November 14, 2023 12:58
Sign up for freeto subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

encryptor lacks sufficient typing

4 participants

@mikesposito@legobeat@mcmire@Gudahtt