Skip to content

Commit 9e1eb22

Browse files
committed
feat: migrate remaining sync decrypt/encrypt calls
Ticket: WCN-284
1 parent 37cde79 commit 9e1eb22

47 files changed

Lines changed: 467 additions & 231 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

modules/abstract-cosmos/src/cosmosCoin.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -243,7 +243,7 @@ export class CosmosCoin<CustomMessage = never> extends BaseCoin {
243243
throw new Error('Invalid key format');
244244
}
245245

246-
return await ECDSAUtils.getMpcV2RecoveryKeyShares(userKey, backupKey, walletPassphrase);
246+
return await ECDSAUtils.getMpcV2RecoveryKeyShares(userKey, backupKey, walletPassphrase, this.bitgo);
247247
}
248248

249249
/**
@@ -491,7 +491,8 @@ export class CosmosCoin<CustomMessage = never> extends BaseCoin {
491491
const { userKeyShare, backupKeyShare, commonKeyChain } = await ECDSAUtils.getMpcV2RecoveryKeyShares(
492492
userKey,
493493
backupKey,
494-
params.walletPassphrase
494+
params.walletPassphrase,
495+
this.bitgo
495496
); // baseAddress is not extracted
496497

497498
const MPC = new Ecdsa();

modules/abstract-eth/src/abstractEthLikeNewCoins.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2250,7 +2250,8 @@ export abstract class AbstractEthLikeNewCoins extends AbstractEthLikeCoin {
22502250
const { userKeyShare, backupKeyShare, commonKeyChain } = await ECDSAUtils.getMpcV2RecoveryKeyShares(
22512251
userPublicOrPrivateKeyShare,
22522252
backupPrivateOrPublicKeyShare,
2253-
params.walletPassphrase
2253+
params.walletPassphrase,
2254+
this.bitgo
22542255
);
22552256

22562257
const { gasLimit, gasPrice } = await this.getGasValues(params);

modules/abstract-lightning/src/wallet/lightning.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -265,7 +265,7 @@ export class LightningWallet implements ILightningWallet {
265265
}
266266
const signature = createMessageSignature(
267267
t.exact(LightningPaymentRequest).encode(params),
268-
this.wallet.bitgo.decrypt({ password: params.passphrase, input: userAuthKeyEncryptedPrv })
268+
await this.wallet.bitgo.decryptAsync({ password: params.passphrase, input: userAuthKeyEncryptedPrv })
269269
);
270270

271271
const paymentIntent: { intent: LightningPaymentIntent } = {
@@ -390,7 +390,7 @@ export class LightningWallet implements ILightningWallet {
390390
}
391391
const signature = createMessageSignature(
392392
transactionRequestCreate.transactions[0].unsignedTx.serializedTxHex,
393-
this.wallet.bitgo.decrypt({ password: params.passphrase, input: userAuthKeyEncryptedPrv })
393+
await this.wallet.bitgo.decryptAsync({ password: params.passphrase, input: userAuthKeyEncryptedPrv })
394394
);
395395

396396
const transactionRequestWithSignature = (await this.wallet.bitgo

modules/abstract-lightning/src/wallet/selfCustodialLightning.ts

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -4,38 +4,38 @@ import { getLightningAuthKeychains, ILightningWallet, LightningWallet } from './
44
import { createMessageSignature, deriveLightningServiceSharedSecret, isLightningCoinName } from '../lightning';
55
import * as t from 'io-ts';
66

7-
function encryptWalletUpdateRequest(
7+
async function encryptWalletUpdateRequest(
88
wallet: sdkcore.IWallet,
99
params: UpdateLightningWalletClientRequest,
1010
userAuthKeyEncryptedPrv: string
11-
): UpdateLightningWalletEncryptedRequest {
11+
): Promise<UpdateLightningWalletEncryptedRequest> {
1212
const coinName = wallet.coin() as 'tlnbtc' | 'lnbtc';
1313

1414
const requestWithEncryption: Partial<UpdateLightningWalletClientRequest & UpdateLightningWalletEncryptedRequest> = {
1515
...params,
1616
};
1717

18-
const userAuthXprv = wallet.bitgo.decrypt({
18+
const userAuthXprv = await wallet.bitgo.decryptAsync({
1919
password: params.passphrase,
2020
input: userAuthKeyEncryptedPrv,
2121
});
2222

2323
if (params.signerTlsKey) {
24-
requestWithEncryption.encryptedSignerTlsKey = wallet.bitgo.encrypt({
24+
requestWithEncryption.encryptedSignerTlsKey = await wallet.bitgo.encryptAsync({
2525
password: params.passphrase,
2626
input: params.signerTlsKey,
2727
});
2828
}
2929

3030
if (params.signerAdminMacaroon) {
31-
requestWithEncryption.encryptedSignerAdminMacaroon = wallet.bitgo.encrypt({
31+
requestWithEncryption.encryptedSignerAdminMacaroon = await wallet.bitgo.encryptAsync({
3232
password: params.passphrase,
3333
input: params.signerAdminMacaroon,
3434
});
3535
}
3636

3737
if (params.signerMacaroon) {
38-
requestWithEncryption.encryptedSignerMacaroon = wallet.bitgo.encrypt({
38+
requestWithEncryption.encryptedSignerMacaroon = await wallet.bitgo.encryptAsync({
3939
password: deriveLightningServiceSharedSecret(coinName, userAuthXprv).toString('hex'),
4040
input: params.signerMacaroon,
4141
});
@@ -86,10 +86,10 @@ export async function updateWalletCoinSpecific(
8686
if (!userAuthKeyEncryptedPrv) {
8787
throw new Error(`user auth key is missing encrypted private key`);
8888
}
89-
const updateRequestWithEncryption = encryptWalletUpdateRequest(wallet, params, userAuthKeyEncryptedPrv);
89+
const updateRequestWithEncryption = await encryptWalletUpdateRequest(wallet, params, userAuthKeyEncryptedPrv);
9090
const signature = createMessageSignature(
9191
updateRequestWithEncryption,
92-
wallet.bitgo.decrypt({ password: params.passphrase, input: userAuthKeyEncryptedPrv })
92+
await wallet.bitgo.decryptAsync({ password: params.passphrase, input: userAuthKeyEncryptedPrv })
9393
);
9494
const coinSpecific = {
9595
[wallet.coin()]: {

modules/abstract-utxo/src/abstractUtxoCoin.ts

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -94,7 +94,7 @@ import {
9494
stringToBufferTryFormats,
9595
} from './transaction/decode';
9696
import { fetchKeychains, toBip32Triple, UtxoKeychain } from './keychains';
97-
import { verifyKeySignature, verifyUserPublicKey } from './verifyKey';
97+
import { verifyKeySignature, verifyUserPublicKey, verifyUserPublicKeyAsync } from './verifyKey';
9898
import { getPolicyForEnv } from './descriptor/validatePolicy';
9999
import { signTransaction } from './transaction/signTransaction';
100100
import { isUtxoWalletData, UtxoWallet } from './wallet';
@@ -706,6 +706,13 @@ export abstract class AbstractUtxoCoin
706706
return verifyUserPublicKey(this.bitgo, params);
707707
}
708708

709+
/**
710+
* @deprecated - use function verifyUserPublicKeyAsync instead
711+
*/
712+
protected async verifyUserPublicKeyAsync(params: VerifyUserPublicKeyOptions): Promise<boolean> {
713+
return await verifyUserPublicKeyAsync(this.bitgo, params);
714+
}
715+
709716
/**
710717
* @deprecated - use function verifyKeySignature instead
711718
*/

modules/abstract-utxo/src/recovery/backupKeyRecovery.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import {
33
BitGoBase,
44
ErrorNoInputToRecover,
55
getKrsProvider,
6-
getBip32Keys as getBip32KeysFromSdkCore,
6+
getBip32KeysAsync as getBip32KeysFromSdkCore,
77
isTriple,
88
krsProviders,
99
Triple,
@@ -410,8 +410,8 @@ export function formatBackupKeyRecoveryResult(
410410
return txInfo;
411411
}
412412

413-
function getBip32Keys(bitgo: BitGoBase, params: RecoverParams): Triple<BIP32> {
414-
const keys = getBip32KeysFromSdkCore(bitgo, params, { requireBitGoXpub: true });
413+
async function getBip32Keys(bitgo: BitGoBase, params: RecoverParams): Promise<Triple<BIP32>> {
414+
const keys = await getBip32KeysFromSdkCore(bitgo, params, { requireBitGoXpub: true });
415415
if (!isTriple(keys)) {
416416
throw new Error(`expected key triple`);
417417
}
@@ -469,7 +469,7 @@ export async function backupKeyRecovery(
469469
}
470470

471471
// check whether key material and password authenticate the users and return parent keys of all three keys of the wallet
472-
const keys = getBip32Keys(bitgo, params);
472+
const keys = await getBip32Keys(bitgo, params);
473473
const walletKeys = fixedScriptWallet.RootWalletKeys.from({
474474
triple: keys,
475475
derivationPrefixes: [params.userKeyPath || 'm/0/0', 'm/0/0', 'm/0/0'],

modules/abstract-utxo/src/recovery/crossChainRecovery.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import { BIP32, CoinName, fixedScriptWallet, address as wasmAddress } from '@bitgo/wasm-utxo';
2+
import { decryptAsync } from '@bitgo/sdk-api';
23
import { BitGoBase, IWallet, Keychain, Triple, Wallet } from '@bitgo/sdk-core';
3-
import { decrypt } from '@bitgo/sdk-api';
44

55
import { AbstractUtxoCoin, TransactionInfo } from '../abstractUtxoCoin';
66
import { signAndVerifyPsbt } from '../transaction/fixedScript/signTransaction';
@@ -313,7 +313,7 @@ async function getPrv(xprv?: string, passphrase?: string, wallet?: IWallet | Wal
313313
encryptedPrv = (await (wallet as WalletV1).getEncryptedUserKeychain()).encryptedXprv;
314314
}
315315

316-
return getPrv(decrypt(passphrase, encryptedPrv));
316+
return getPrv(await decryptAsync(passphrase, encryptedPrv));
317317
}
318318

319319
/**

modules/abstract-utxo/src/transaction/fixedScript/verifyTransaction.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ import * as utxolib from '@bitgo/utxo-lib';
66

77
import { AbstractUtxoCoin, VerifyTransactionOptions } from '../../abstractUtxoCoin';
88
import { Output, ParsedTransaction } from '../types';
9-
import { verifyCustomChangeKeySignatures, verifyKeySignature, verifyUserPublicKey } from '../../verifyKey';
9+
import { verifyCustomChangeKeySignatures, verifyKeySignature, verifyUserPublicKeyAsync } from '../../verifyKey';
1010
import { getPsbtTxInputs, getTxInputs } from '../fetchInputs';
1111

1212
const debug = buildDebug('bitgo:abstract-utxo:verifyTransaction');
@@ -80,7 +80,7 @@ export async function verifyTransaction<TNumber extends bigint | number>(
8080
let userPublicKeyVerified = false;
8181
try {
8282
// verify the user public key matches the private key - this will throw if there is no match
83-
userPublicKeyVerified = verifyUserPublicKey(bitgo, {
83+
userPublicKeyVerified = await verifyUserPublicKeyAsync(bitgo, {
8484
userKeychain: keychains.user,
8585
disableNetworking,
8686
txParams,

modules/abstract-utxo/src/verifyKey.ts

Lines changed: 47 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ import assert from 'assert';
77

88
import buildDebug from 'debug';
99
import { BIP32, message } from '@bitgo/wasm-utxo';
10-
import { BitGoBase, decryptKeychainPrivateKey, KeyIndices } from '@bitgo/sdk-core';
10+
import { BitGoBase, decryptKeychainPrivateKey, decryptKeychainPrivateKeyAsync, KeyIndices } from '@bitgo/sdk-core';
1111

1212
import { VerifyKeySignaturesOptions, VerifyUserPublicKeyOptions } from './abstractUtxoCoin';
1313
import { ParsedTransaction } from './transaction/types';
@@ -81,39 +81,65 @@ export function verifyCustomChangeKeySignatures<TNumber extends number | bigint>
8181
return true;
8282
}
8383

84+
function verifyUserPublicKeyWithPrv(
85+
userKeychain: NonNullable<VerifyUserPublicKeyOptions['userKeychain']>,
86+
userPrv: string | undefined,
87+
disableNetworking: boolean | undefined
88+
): boolean {
89+
const userPub = userKeychain.pub;
90+
91+
if (!userPrv) {
92+
const errorMessage = 'user private key unavailable for verification';
93+
if (disableNetworking) {
94+
console.log(errorMessage);
95+
return false;
96+
} else {
97+
throw new Error(errorMessage);
98+
}
99+
}
100+
101+
const userPrivateKey = BIP32.fromBase58(userPrv);
102+
if (userPrivateKey.toBase58() === userPrivateKey.neutered().toBase58()) {
103+
throw new Error('user private key is only public');
104+
}
105+
if (userPrivateKey.neutered().toBase58() !== userPub) {
106+
throw new Error('user private key does not match public key');
107+
}
108+
109+
return true;
110+
}
111+
84112
/**
85-
* Decrypt the wallet's user private key and verify that the claimed public key matches
113+
* TODO: Deprecate in favor of verifyUserPublicKeyAsync once v2 encryption is default.
114+
* Decrypt the wallet's user private key and verify that the claimed public key matches (sync, v1 only).
86115
*/
87116
export function verifyUserPublicKey(bitgo: BitGoBase, params: VerifyUserPublicKeyOptions): boolean {
88117
const { userKeychain, txParams, disableNetworking } = params;
89118
if (!userKeychain) {
90119
throw new Error('user keychain is required');
91120
}
92121

93-
const userPub = userKeychain.pub;
94-
95122
let userPrv = userKeychain.prv;
96123
if (!userPrv && txParams.walletPassphrase) {
97124
userPrv = decryptKeychainPrivateKey(bitgo, userKeychain, txParams.walletPassphrase);
98125
}
99126

100-
if (!userPrv) {
101-
const errorMessage = 'user private key unavailable for verification';
102-
if (disableNetworking) {
103-
console.log(errorMessage);
104-
return false;
105-
} else {
106-
throw new Error(errorMessage);
107-
}
108-
} else {
109-
const userPrivateKey = BIP32.fromBase58(userPrv);
110-
if (userPrivateKey.toBase58() === userPrivateKey.neutered().toBase58()) {
111-
throw new Error('user private key is only public');
112-
}
113-
if (userPrivateKey.neutered().toBase58() !== userPub) {
114-
throw new Error('user private key does not match public key');
115-
}
127+
return verifyUserPublicKeyWithPrv(userKeychain, userPrv, disableNetworking);
128+
}
129+
130+
/**
131+
* Async version of verifyUserPublicKey with v2 encrypt/decrypt support.
132+
*/
133+
export async function verifyUserPublicKeyAsync(bitgo: BitGoBase, params: VerifyUserPublicKeyOptions): Promise<boolean> {
134+
const { userKeychain, txParams, disableNetworking } = params;
135+
if (!userKeychain) {
136+
throw new Error('user keychain is required');
116137
}
117138

118-
return true;
139+
let userPrv = userKeychain.prv;
140+
if (!userPrv && txParams.walletPassphrase) {
141+
userPrv = await decryptKeychainPrivateKeyAsync(bitgo, userKeychain, txParams.walletPassphrase);
142+
}
143+
144+
return verifyUserPublicKeyWithPrv(userKeychain, userPrv, disableNetworking);
119145
}

modules/bitgo/test/v2/unit/keychains.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1076,7 +1076,7 @@ describe('V2 Keychains', function () {
10761076
updateKeychainStub = sandbox.stub().returns({ result: sandbox.stub().resolves() });
10771077
sandbox.stub(BitGo.prototype, 'put').returns({ send: updateKeychainStub });
10781078
createKeypairStub = sandbox.stub(ofcKeychains, 'create').returns(mockNewKeypair);
1079-
encryptionStub = sandbox.stub(BitGo.prototype, 'encrypt').returns('newEncryptedPrv');
1079+
encryptionStub = sandbox.stub(BitGo.prototype, 'encryptAsync').resolves('newEncryptedPrv');
10801080
});
10811081

10821082
afterEach(function () {
@@ -1088,7 +1088,7 @@ describe('V2 Keychains', function () {
10881088

10891089
await ofcKeychains.rotateKeychain({ id: mockOfcKeychain.id, password: '1234' });
10901090
sinon.assert.called(createKeypairStub);
1091-
sinon.assert.calledWith(encryptionStub, { input: mockNewKeypair.prv, password: '1234' });
1091+
sinon.assert.calledWith(encryptionStub, { input: mockNewKeypair.prv, password: '1234', encryptionVersion: 2 });
10921092
sinon.assert.calledWith(updateKeychainStub, {
10931093
pub: mockNewKeypair.pub,
10941094
encryptedPrv: 'newEncryptedPrv',

0 commit comments

Comments
 (0)