Skip to content
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

fix: make secret encrypt to async #6407

Merged
merged 6 commits into from
Jan 3, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions jest-setup.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
/* eslint-disable no-undef */
// require('react-native-reanimated').setUpTests();

// FIX: ReferenceError: self is not defined
Expand Down
2 changes: 1 addition & 1 deletion jest.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ module.exports = async () => {
[
'./node_modules/jest-html-reporter',
{
'pageTitle': 'Test Report',
'pageTitle': 'Jest UnitTest Report',
},
],
],
Expand Down
4 changes: 2 additions & 2 deletions packages/core/@tests/coreTestsUtils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -216,7 +216,7 @@ async function expectSignTransactionOk({
const resultImported = await coreApi.signTransaction({
...signTxPayload,
credentials: {
imported: encryptImportedCredential({
imported: await encryptImportedCredential({
password,
credential: { privateKey: account.xpvtRaw || account.privateKeyRaw },
}),
Expand Down Expand Up @@ -258,7 +258,7 @@ async function expectSignMessageOk({
const resultImported = await coreApi.signMessage({
...signMsgPayload,
credentials: {
imported: encryptImportedCredential({
imported: await encryptImportedCredential({
password,
credential: { privateKey: account.privateKeyRaw },
}),
Expand Down
10 changes: 6 additions & 4 deletions packages/core/src/base/CoreChainApiBase.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ import {
decrypt,
decryptImportedCredential,
ed25519,
encrypt,
encryptAsync,
nistp256,
secp256k1,
} from '../secret';
Expand Down Expand Up @@ -140,7 +140,9 @@ export abstract class CoreChainApiBase {
password,
credential: credentials.imported,
});
const encryptPrivateKey = bufferUtils.bytesToHex(encrypt(password, p));
const encryptPrivateKey = bufferUtils.bytesToHex(
await encryptAsync({ password, data: p }),
);
privateKeys[account.path] = encryptPrivateKey;
privateKeys[''] = encryptPrivateKey;
}
Expand Down Expand Up @@ -170,7 +172,7 @@ export abstract class CoreChainApiBase {
);
}

const keys = batchGetPrivateKeys(
const keys = await batchGetPrivateKeys(
curve,
hdCredential,
password,
Expand Down Expand Up @@ -205,7 +207,7 @@ export abstract class CoreChainApiBase {
let pvtkeyInfos: ISecretPrivateKeyInfo[] = [];

if (isPrivateKeyMode) {
pvtkeyInfos = batchGetPrivateKeys(
pvtkeyInfos = await batchGetPrivateKeys(
curve,
hdCredential,
password,
Expand Down
7 changes: 5 additions & 2 deletions packages/core/src/chains/ada/CoreChainSoftware.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { checkIsDefined } from '@onekeyhq/shared/src/utils/assertUtils';
import bufferUtils from '@onekeyhq/shared/src/utils/bufferUtils';

import { CoreChainApiBase } from '../../base/CoreChainApiBase';
import { decrypt, encrypt } from '../../secret';
import { decrypt, encryptAsync } from '../../secret';
import {
ECoreApiExportedSecretKeyType,
type ICoreApiGetAddressItem,
Expand Down Expand Up @@ -53,7 +53,10 @@ export default class CoreChainSoftware extends CoreChainApiBase {

const xprv = await generateExportedCredential(password, hdCredential, path);
const privateKey = decodePrivateKeyByXprv(xprv);
const privateKeyEncrypt = encrypt(password, privateKey);
const privateKeyEncrypt = await encryptAsync({
password,
data: privateKey,
});

const map: ICoreApiPrivateKeysMap = {
[path]: bufferUtils.bytesToHex(privateKeyEncrypt),
Expand Down
18 changes: 9 additions & 9 deletions packages/core/src/chains/btc/CoreChainSoftware.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ import {
BaseBip32KeyDeriver,
batchGetPublicKeysAsync,
decrypt,
encrypt,
encryptAsync,
mnemonicFromEntropyAsync,
mnemonicToSeedAsync,
secp256k1,
Expand Down Expand Up @@ -433,15 +433,15 @@ export default class CoreChainSoftwareBtc extends CoreChainApiBase {
return psbt;
}

private appendImportedRelPathPrivateKeys({
private async appendImportedRelPathPrivateKeys({
privateKeys,
password,
relPaths,
}: {
privateKeys: ICoreApiPrivateKeysMap;
password: string;
relPaths?: string[];
}): ICoreApiPrivateKeysMap {
}): Promise<ICoreApiPrivateKeysMap> {
const deriver = new BaseBip32KeyDeriver(
Buffer.from('Bitcoin seed'),
secp256k1,
Expand All @@ -457,12 +457,12 @@ export default class CoreChainSoftwareBtc extends CoreChainApiBase {

const cache: Record<string, IBip32ExtendedKey> = {};

relPaths?.forEach((relPath) => {
for (const relPath of relPaths ?? []) {
const pathComponents = relPath.split('/');

let currentPath = '';
let parent = startKey;
pathComponents.forEach((pathComponent) => {
for (const pathComponent of pathComponents) {
currentPath =
currentPath.length > 0
? `${currentPath}/${pathComponent}`
Expand All @@ -475,13 +475,13 @@ export default class CoreChainSoftwareBtc extends CoreChainApiBase {
cache[currentPath] = thisPrivKey;
}
parent = cache[currentPath];
});
}

// TODO use dbAccountAddresses save fullPath/relPath key
privateKeys[relPath] = bufferUtils.bytesToHex(
encrypt(password, cache[relPath].key),
await encryptAsync({ password, data: cache[relPath].key }),
);
});
}
return privateKeys;
}

Expand Down Expand Up @@ -703,7 +703,7 @@ export default class CoreChainSoftwareBtc extends CoreChainApiBase {
curve: curveName,
});
if (isImported) {
this.appendImportedRelPathPrivateKeys({
await this.appendImportedRelPathPrivateKeys({
privateKeys,
password,
relPaths,
Expand Down
17 changes: 12 additions & 5 deletions packages/core/src/chains/dot/CoreChainSoftware.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,11 @@ import { CoreChainApiBase } from '../../base/CoreChainApiBase';
import {
decrypt,
decryptImportedCredential,
encrypt,
encryptAsync,
mnemonicFromEntropy,
} from '../../secret';
import {
ECoreApiExportedSecretKeyType,
type ICoreApiGetAddressItem,
type ICoreApiGetAddressQueryImported,
type ICoreApiGetAddressQueryPublicKey,
Expand All @@ -30,7 +31,6 @@ import {
type ICurveName,
type ISignedTxPro,
} from '../../types';
import { ECoreApiExportedSecretKeyType } from '../../types';
import { slicePathTemplate } from '../../utils';

import { serializeMessage, serializeSignedTransaction } from './sdkDot';
Expand Down Expand Up @@ -95,16 +95,21 @@ export default class CoreChainSoftware extends CoreChainApiBase {
const usedRelativePaths = relPaths || [pathComponents.pop() as string];
const basePath = pathComponents.join('/');
const mnemonic = mnemonicFromEntropy(credentials.hd, password);
const keys = usedRelativePaths.map((relPath) => {
const keysPromised = usedRelativePaths.map(async (relPath) => {
const path = `${basePath}/${relPath}`;

const keyPair = derivationHdLedger(mnemonic, path);
return {
path,
key: encrypt(password, Buffer.from(keyPair.secretKey.slice(0, 32))),
key: await encryptAsync({
password,
data: Buffer.from(keyPair.secretKey.slice(0, 32)),
}),
};
});

const keys = await Promise.all(keysPromised);

privateKeys = keys.reduce(
(ret, key) => ({ ...ret, [key.path]: bufferUtils.bytesToHex(key.key) }),
{},
Expand All @@ -115,7 +120,9 @@ export default class CoreChainSoftware extends CoreChainApiBase {
password,
credential: credentials.imported,
});
const encryptPrivateKey = bufferUtils.bytesToHex(encrypt(password, p));
const encryptPrivateKey = bufferUtils.bytesToHex(
await encryptAsync({ password, data: p }),
);
privateKeys[account.path] = encryptPrivateKey;
privateKeys[''] = encryptPrivateKey;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ export const generateNativeSegwitAccounts = async ({
(index) => `${index.toString()}'`, // btc
);

const pubkeyInfos = batchGetPublicKeys(
const pubkeyInfos = await batchGetPublicKeys(
curve,
hdCredential,
password,
Expand Down
49 changes: 25 additions & 24 deletions packages/core/src/secret/__tests__/secret-aes256.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -85,11 +85,12 @@ describe('AES256 Encryption Tests', () => {
expect(decrypted.toString()).toBe(TEST_DATA);
});

it('should throw on incorrect password', () => {
it('should throw on incorrect password', async () => {
const encrypted = encrypt(TEST_PASSWORD, TEST_DATA_HEX);
expect(() =>
decrypt(encodePassword({ password: 'wrong-password' }), encrypted),
).toThrow();
const encodedPassword = await encodePassword({
password: 'wrong-password',
});
expect(() => decrypt(encodedPassword, encrypted)).toThrow();
});

it('should throw on empty password', () => {
Expand Down Expand Up @@ -214,8 +215,8 @@ describe('AES256 Encryption Tests', () => {
});

describe('encodePassword/decodePassword', () => {
it('should encode and decode password with snapshot', () => {
const encoded = encodePassword({
it('should encode and decode password with snapshot', async () => {
const encoded = await encodePassword({
password: TEST_PASSWORD,
key: 'test-key',
});
Expand All @@ -228,8 +229,8 @@ describe('AES256 Encryption Tests', () => {
expect(decoded).toBe(TEST_PASSWORD);
});

it('should throw on incorrect key', () => {
const encoded = encodePassword({
it('should throw on incorrect key', async () => {
const encoded = await encodePassword({
password: TEST_PASSWORD,
key: 'test-key',
});
Expand All @@ -242,15 +243,15 @@ describe('AES256 Encryption Tests', () => {
});

// TODO empty key should throw
it.skip('should throw on empty key', () => {
expect(() =>
it.skip('should throw on empty key', async () => {
await expect(
encodePassword({
password: TEST_PASSWORD,
key: '',
}),
).toThrow();
).rejects.toThrow();

const encoded = encodePassword({
const encoded = await encodePassword({
password: TEST_PASSWORD,
key: 'test-key',
});
Expand All @@ -264,8 +265,8 @@ describe('AES256 Encryption Tests', () => {
});

describe('encodeSensitiveText/decodeSensitiveText', () => {
it('should encode and decode sensitive text with snapshot', () => {
const encoded = encodeSensitiveText({
it('should encode and decode sensitive text with snapshot', async () => {
const encoded = await encodeSensitiveText({
text: TEST_DATA,
key: 'test-key',
});
Expand All @@ -278,8 +279,8 @@ describe('AES256 Encryption Tests', () => {
expect(decoded).toBe(TEST_DATA);
});

it('should throw on incorrect key', () => {
const encoded = encodeSensitiveText({
it('should throw on incorrect key', async () => {
const encoded = await encodeSensitiveText({
text: TEST_DATA,
key: 'test-key',
});
Expand All @@ -292,15 +293,15 @@ describe('AES256 Encryption Tests', () => {
});

// TODO empty key should throw
it.skip('should throw on empty key', () => {
it.skip('should throw on empty key', async () => {
expect(() =>
encodeSensitiveText({
text: TEST_DATA,
key: '',
}),
).toThrow();

const encoded = encodeSensitiveText({
const encoded = await encodeSensitiveText({
text: TEST_DATA,
key: 'test-key',
});
Expand Down Expand Up @@ -375,17 +376,17 @@ describe('AES256 Encryption Tests', () => {
});

describe('isEncodedSensitiveText and ensureSensitiveTextEncoded', () => {
it('should correctly identify encoded sensitive text', () => {
const encoded = encodeSensitiveText({
it('should correctly identify encoded sensitive text', async () => {
const encoded = await encodeSensitiveText({
text: TEST_DATA,
key: 'test-key',
});
expect(isEncodedSensitiveText(encoded)).toBe(true);
expect(isEncodedSensitiveText('not-encoded-text')).toBe(false);
});

it('should handle both aes and xor prefixes', () => {
const aesEncoded = encodeSensitiveText({
it('should handle both aes and xor prefixes', async () => {
const aesEncoded = await encodeSensitiveText({
text: TEST_DATA,
key: 'test-key',
});
Expand All @@ -404,8 +405,8 @@ describe('AES256 Encryption Tests', () => {
);
});

it('should not throw for valid encoded text in ensureSensitiveTextEncoded', () => {
const encoded = encodeSensitiveText({
it('should not throw for valid encoded text in ensureSensitiveTextEncoded', async () => {
const encoded = await encodeSensitiveText({
text: TEST_DATA,
key: 'test-key',
});
Expand Down
Loading
Loading