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

Commit 189f85b

Browse files
committed
Export key for encrypted key login
1 parent 462cd15 commit 189f85b

File tree

3 files changed

+40
-14
lines changed

3 files changed

+40
-14
lines changed

index.js

Lines changed: 34 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ const KEYRINGS_TYPE_MAP = {
1414
HD_KEYRING: 'HD Key Tree',
1515
SIMPLE_KEYRING: 'Simple Key Pair',
1616
};
17+
1718
/**
1819
* Strip the hex prefix from an address, if present
1920
* @param {string} address - The address that might be hex prefixed.
@@ -145,7 +146,7 @@ class KeyringController extends EventEmitter {
145146
*/
146147
async setLocked() {
147148
// set locked
148-
this.password = null;
149+
delete this.encryptionKey;
149150
this.memStore.updateState({ isUnlocked: false });
150151
// remove keyrings
151152
this.keyrings = [];
@@ -168,7 +169,15 @@ class KeyringController extends EventEmitter {
168169
* @returns {Promise<Object>} A Promise that resolves to the state.
169170
*/
170171
async submitPassword(password) {
172+
await this.verifyPassword(password);
171173
this.keyrings = await this.unlockKeyrings(password);
174+
await this.persistAllKeyrings(password);
175+
this.setUnlocked();
176+
this.fullUpdate();
177+
}
178+
179+
async submitEncryptionKey(encryptionKey) {
180+
this.keyrings = await this.unlockKeyrings(undefined, encryptionKey);
172181
this.setUnlocked();
173182
this.fullUpdate();
174183
}
@@ -202,7 +211,7 @@ class KeyringController extends EventEmitter {
202211
* @param {Object} opts - The constructor options for the keyring.
203212
* @returns {Promise<Keyring>} The new keyring.
204213
*/
205-
async addNewKeyring(type, opts) {
214+
async addNewKeyring(type, opts, password) {
206215
const Keyring = this.getKeyringClassForType(type);
207216
const keyring = new Keyring(opts);
208217
if ((!opts || !opts.mnemonic) && type === KEYRINGS_TYPE_MAP.HD_KEYRING) {
@@ -214,7 +223,7 @@ class KeyringController extends EventEmitter {
214223
await this.checkForDuplicate(type, accounts);
215224

216225
this.keyrings.push(keyring);
217-
await this.persistAllKeyrings();
226+
await this.persistAllKeyrings(password);
218227

219228
await this._updateMemStoreKeyrings();
220229
this.fullUpdate();
@@ -491,10 +500,13 @@ class KeyringController extends EventEmitter {
491500
* @returns {Promise<void>} - A promise that resolves if the operation was successful.
492501
*/
493502
async createFirstKeyTree(password) {
494-
this.password = password;
495503
this.clearKeyrings();
496504

497-
const keyring = await this.addNewKeyring(KEYRINGS_TYPE_MAP.HD_KEYRING);
505+
const keyring = await this.addNewKeyring(
506+
KEYRINGS_TYPE_MAP.HD_KEYRING,
507+
{},
508+
password,
509+
);
498510
const [firstAccount] = await keyring.getAccounts();
499511
if (!firstAccount) {
500512
throw new Error('KeyringController - No account found on keychain.');
@@ -516,12 +528,11 @@ class KeyringController extends EventEmitter {
516528
* @param {string} password - The keyring controller password.
517529
* @returns {Promise<boolean>} Resolves to true once keyrings are persisted.
518530
*/
519-
async persistAllKeyrings(password = this.password) {
531+
async persistAllKeyrings(password) {
520532
if (typeof password !== 'string') {
521533
throw new Error('KeyringController - password is not a string');
522534
}
523535

524-
this.password = password;
525536
const serializedKeyrings = await Promise.all(
526537
this.keyrings.map(async (keyring) => {
527538
const [type, data] = await Promise.all([
@@ -531,11 +542,13 @@ class KeyringController extends EventEmitter {
531542
return { type, data };
532543
}),
533544
);
534-
const encryptedString = await this.encryptor.encrypt(
535-
this.password,
545+
546+
const vault = await this.encryptor.encrypt(
547+
password,
536548
serializedKeyrings,
537549
);
538-
this.store.updateState({ vault: encryptedString });
550+
551+
this.store.updateState({ vault });
539552
return true;
540553
}
541554

@@ -548,15 +561,23 @@ class KeyringController extends EventEmitter {
548561
* @param {string} password - The keyring controller password.
549562
* @returns {Promise<Array<Keyring>>} The keyrings.
550563
*/
551-
async unlockKeyrings(password) {
564+
async unlockKeyrings(password, encryptionKey) {
552565
const encryptedVault = this.store.getState().vault;
553566
if (!encryptedVault) {
554567
throw new Error('Cannot unlock without a previous vault.');
555568
}
556569

557570
await this.clearKeyrings();
558-
const vault = await this.encryptor.decrypt(password, encryptedVault);
559-
this.password = password;
571+
572+
let vault;
573+
if (password) {
574+
const result = await this.encryptor.decrypt(password, encryptedVault);
575+
vault = result.vault;
576+
this.encryptionKey = result.extractedKeyString;
577+
} else {
578+
vault = (await this.encryptor.decryptWithEncryptedKeyString(encryptionKey)).vault;
579+
}
580+
560581
await Promise.all(vault.map(this._restoreKeyring.bind(this)));
561582
await this._updateMemStoreKeyrings();
562583
return this.keyrings;

test/index.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ describe('KeyringController', function () {
2929
});
3030

3131
await keyringController.createNewVaultAndKeychain(password);
32+
await keyringController.submitPassword(password);
3233
});
3334

3435
afterEach(function () {
@@ -63,7 +64,7 @@ describe('KeyringController', function () {
6364
describe('submitPassword', function () {
6465
it('should not create new keyrings when called in series', async function () {
6566
await keyringController.createNewVaultAndKeychain(password);
66-
await keyringController.persistAllKeyrings();
67+
await keyringController.persistAllKeyrings(password);
6768
expect(keyringController.keyrings).toHaveLength(1);
6869

6970
await keyringController.submitPassword(`${password}a`);

test/lib/mock-encryptor.js

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,10 @@ module.exports = {
1010
return Promise.resolve(mockHex);
1111
}),
1212

13+
decryptWithEncryptedKeyString(_keyStr) {
14+
return this.decrypt();
15+
},
16+
1317
decrypt(_password, _text) {
1418
return Promise.resolve(cacheVal || {});
1519
},

0 commit comments

Comments
 (0)