Skip to content
Draft
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
10 changes: 5 additions & 5 deletions modules/abstract-eth/src/abstractEthLikeNewCoins.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1482,7 +1482,7 @@ export abstract class AbstractEthLikeNewCoins extends AbstractEthLikeCoin {

if (!userKey.startsWith('xpub') && !userKey.startsWith('xprv')) {
try {
userKey = await this.bitgo.decryptAsync({
userKey = await this.bitgo.decrypt({
input: userKey,
password: params.walletPassphrase,
});
Expand All @@ -1501,7 +1501,7 @@ export abstract class AbstractEthLikeNewCoins extends AbstractEthLikeCoin {
let backupPrv;

try {
backupPrv = await this.bitgo.decryptAsync({
backupPrv = await this.bitgo.decrypt({
input: backupKey,
password: params.walletPassphrase,
});
Expand Down Expand Up @@ -1674,7 +1674,7 @@ export abstract class AbstractEthLikeNewCoins extends AbstractEthLikeCoin {

let userKeyPrv;
try {
userKeyPrv = await this.bitgo.decryptAsync({
userKeyPrv = await this.bitgo.decrypt({
input: params.encryptedPrv,
password: params.walletPassphrase,
});
Expand Down Expand Up @@ -1753,7 +1753,7 @@ export abstract class AbstractEthLikeNewCoins extends AbstractEthLikeCoin {
if (params.walletPassphrase) {
if (!userKey.startsWith('xpub') && !userKey.startsWith('xprv')) {
try {
userKeyPrv = await this.bitgo.decryptAsync({
userKeyPrv = await this.bitgo.decrypt({
input: userKey,
password: params.walletPassphrase,
});
Expand Down Expand Up @@ -2559,7 +2559,7 @@ export abstract class AbstractEthLikeNewCoins extends AbstractEthLikeCoin {
const walletPassphrase = buildParams.walletPassphrase;

const userKeychain = await this.keychains().get({ id: wallet.keyIds()[0] });
const userPrv = await wallet.getUserPrvAsync({ keychain: userKeychain, walletPassphrase });
const userPrv = await wallet.getUserPrv({ keychain: userKeychain, walletPassphrase });
const userPrvBuffer = bip32.fromBase58(userPrv).privateKey;
if (!userPrvBuffer) {
throw new Error('invalid userPrv');
Expand Down
4 changes: 2 additions & 2 deletions modules/abstract-eth/src/ethLikeToken.ts
Original file line number Diff line number Diff line change
Expand Up @@ -219,7 +219,7 @@ export class EthLikeToken extends AbstractEthLikeNewCoins {
// Decrypt private keys from KeyCard values
if (!userKey.startsWith('xpub') && !userKey.startsWith('xprv')) {
try {
userKey = await this.bitgo.decryptAsync({
userKey = await this.bitgo.decrypt({
input: userKey,
password: params.walletPassphrase,
});
Expand All @@ -239,7 +239,7 @@ export class EthLikeToken extends AbstractEthLikeNewCoins {
let backupPrv;

try {
backupPrv = await this.bitgo.decryptAsync({
backupPrv = await this.bitgo.decrypt({
input: backupKey,
password: params.walletPassphrase,
});
Expand Down
4 changes: 2 additions & 2 deletions modules/abstract-lightning/src/wallet/lightning.ts
Original file line number Diff line number Diff line change
Expand Up @@ -265,7 +265,7 @@ export class LightningWallet implements ILightningWallet {
}
const signature = createMessageSignature(
t.exact(LightningPaymentRequest).encode(params),
await this.wallet.bitgo.decryptAsync({ password: params.passphrase, input: userAuthKeyEncryptedPrv })
await this.wallet.bitgo.decrypt({ password: params.passphrase, input: userAuthKeyEncryptedPrv })
);

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

const transactionRequestWithSignature = (await this.wallet.bitgo
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,29 +15,29 @@ async function encryptWalletUpdateRequest(
...params,
};

const userAuthXprv = await wallet.bitgo.decryptAsync({
const userAuthXprv = await wallet.bitgo.decrypt({
password: params.passphrase,
input: userAuthKeyEncryptedPrv,
});

if (params.signerTlsKey) {
requestWithEncryption.encryptedSignerTlsKey = await wallet.bitgo.encryptAsync({
requestWithEncryption.encryptedSignerTlsKey = await wallet.bitgo.encrypt({
password: params.passphrase,
input: params.signerTlsKey,
encryptionVersion: params.encryptionVersion,
});
}

if (params.signerAdminMacaroon) {
requestWithEncryption.encryptedSignerAdminMacaroon = await wallet.bitgo.encryptAsync({
requestWithEncryption.encryptedSignerAdminMacaroon = await wallet.bitgo.encrypt({
password: params.passphrase,
input: params.signerAdminMacaroon,
encryptionVersion: params.encryptionVersion,
});
}

if (params.signerMacaroon) {
requestWithEncryption.encryptedSignerMacaroon = await wallet.bitgo.encryptAsync({
requestWithEncryption.encryptedSignerMacaroon = await wallet.bitgo.encrypt({
password: deriveLightningServiceSharedSecret(coinName, userAuthXprv).toString('hex'),
input: params.signerMacaroon,
encryptionVersion: params.encryptionVersion,
Expand Down Expand Up @@ -92,7 +92,7 @@ export async function updateWalletCoinSpecific(
const updateRequestWithEncryption = await encryptWalletUpdateRequest(wallet, params, userAuthKeyEncryptedPrv);
const signature = createMessageSignature(
updateRequestWithEncryption,
await wallet.bitgo.decryptAsync({ password: params.passphrase, input: userAuthKeyEncryptedPrv })
await wallet.bitgo.decrypt({ password: params.passphrase, input: userAuthKeyEncryptedPrv })
);
const coinSpecific = {
[wallet.coin()]: {
Expand Down
4 changes: 2 additions & 2 deletions modules/abstract-substrate/src/abstractSubstrateCoin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -345,7 +345,7 @@ export class SubstrateCoin extends BaseCoin {
// Decrypt private keys from KeyCard values
let userPrv;
try {
userPrv = await this.bitgo.decryptAsync({
userPrv = await this.bitgo.decrypt({
input: userKey,
password: params.walletPassphrase,
});
Expand All @@ -356,7 +356,7 @@ export class SubstrateCoin extends BaseCoin {

let backupPrv;
try {
backupPrv = await this.bitgo.decryptAsync({
backupPrv = await this.bitgo.decrypt({
input: backupKey,
password: params.walletPassphrase,
});
Expand Down
15 changes: 4 additions & 11 deletions modules/abstract-utxo/src/abstractUtxoCoin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ import { assertFixedScriptWalletAddress, generateAddress } from './address/fixed
import { ParsedTransaction } from './transaction/types';
import { decodeDescriptorPsbt, decodePsbt, encodeTransaction, stringToBufferTryFormats } from './transaction/decode';
import { fetchKeychains, toBip32Triple, UtxoKeychain } from './keychains';
import { verifyKeySignature, verifyUserPublicKey, verifyUserPublicKeyAsync } from './verifyKey';
import { verifyKeySignature, verifyUserPublicKey } from './verifyKey';
import { getPolicyForEnv } from './descriptor/validatePolicy';
import { signTransaction } from './transaction/signTransaction';
import { isUtxoWalletData, UtxoWallet } from './wallet';
Expand Down Expand Up @@ -604,17 +604,10 @@ export abstract class AbstractUtxoCoin extends BaseCoin implements Musig2Partici
}

/**
* @deprecated - use function verifyUserPublicKey instead
* @deprecated - use the exported `verifyUserPublicKey` function instead
*/
protected verifyUserPublicKey(params: VerifyUserPublicKeyOptions): boolean {
return verifyUserPublicKey(this.bitgo, params);
}

/**
* @deprecated - use function verifyUserPublicKeyAsync instead
*/
protected async verifyUserPublicKeyAsync(params: VerifyUserPublicKeyOptions): Promise<boolean> {
return await verifyUserPublicKeyAsync(this.bitgo, params);
protected async verifyUserPublicKey(params: VerifyUserPublicKeyOptions): Promise<boolean> {
return await verifyUserPublicKey(this.bitgo, params);
}

/**
Expand Down
4 changes: 2 additions & 2 deletions modules/abstract-utxo/src/impl/btc/inscriptionBuilder.ts
Original file line number Diff line number Diff line change
Expand Up @@ -260,7 +260,7 @@ export class InscriptionBuilder implements IInscriptionBuilder {
inscriptionData: Buffer
): Promise<SubmitTransactionResponse> {
const userKeychain = await this.wallet.baseCoin.keychains().get({ id: this.wallet.keyIds()[KeyIndices.USER] });
const xprv = await this.wallet.getUserPrvAsync({ keychain: userKeychain, walletPassphrase });
const xprv = await this.wallet.getUserPrv({ keychain: userKeychain, walletPassphrase });

const halfSignedCommitTransaction = (await this.wallet.signTransaction({
prv: xprv,
Expand Down Expand Up @@ -300,7 +300,7 @@ export class InscriptionBuilder implements IInscriptionBuilder {
txPrebuild: PrebuildTransactionResult
): Promise<SubmitTransactionResponse> {
const userKeychain = await this.wallet.baseCoin.keychains().get({ id: this.wallet.keyIds()[KeyIndices.USER] });
const prv = await this.wallet.getUserPrvAsync({ keychain: userKeychain, walletPassphrase });
const prv = await this.wallet.getUserPrv({ keychain: userKeychain, walletPassphrase });

const halfSigned = (await this.wallet.signTransaction({ prv, txPrebuild })) as HalfSignedUtxoTransaction;
return this.wallet.submitTransaction({ halfSigned });
Expand Down
2 changes: 1 addition & 1 deletion modules/abstract-utxo/src/recovery/backupKeyRecovery.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import {
BitGoBase,
ErrorNoInputToRecover,
getKrsProvider,
getBip32KeysAsync as getBip32KeysFromSdkCore,
getBip32Keys as getBip32KeysFromSdkCore,
isTriple,
krsProviders,
Triple,
Expand Down
4 changes: 2 additions & 2 deletions modules/abstract-utxo/src/recovery/crossChainRecovery.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { BIP32, CoinName, fixedScriptWallet, address as wasmAddress } from '@bitgo/wasm-utxo';
import { decryptAsync } from '@bitgo/sdk-api';
import { decrypt } from '@bitgo/sdk-api';
import { BitGoBase, IWallet, Keychain, Triple, Wallet } from '@bitgo/sdk-core';

import { AbstractUtxoCoin, TransactionInfo } from '../abstractUtxoCoin';
Expand Down Expand Up @@ -313,7 +313,7 @@ async function getPrv(xprv?: string, passphrase?: string, wallet?: IWallet | Wal
encryptedPrv = (await (wallet as WalletV1).getEncryptedUserKeychain()).encryptedXprv;
}

return getPrv(await decryptAsync(passphrase, encryptedPrv));
return getPrv(await decrypt(passphrase, encryptedPrv));
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import { hasPsbtMagic } from '@bitgo/wasm-utxo';
import { AbstractUtxoCoin, VerifyTransactionOptions } from '../../abstractUtxoCoin';
import { ParsedTransaction } from '../types';
import { stringToBufferTryFormats } from '../decode';
import { verifyCustomChangeKeySignatures, verifyKeySignature, verifyUserPublicKeyAsync } from '../../verifyKey';
import { verifyCustomChangeKeySignatures, verifyKeySignature, verifyUserPublicKey } from '../../verifyKey';

const debug = buildDebug('bitgo:abstract-utxo:verifyTransaction');

Expand Down Expand Up @@ -80,7 +80,7 @@ export async function verifyTransaction<TNumber extends bigint | number>(
let userPublicKeyVerified = false;
try {
// verify the user public key matches the private key - this will throw if there is no match
userPublicKeyVerified = await verifyUserPublicKeyAsync(bitgo, {
userPublicKeyVerified = await verifyUserPublicKey(bitgo, {
userKeychain: keychains.user,
disableNetworking,
txParams,
Expand Down
27 changes: 5 additions & 22 deletions modules/abstract-utxo/src/verifyKey.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import assert from 'assert';

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

import { VerifyKeySignaturesOptions, VerifyUserPublicKeyOptions } from './abstractUtxoCoin';
import { ParsedTransaction } from './transaction/types';
Expand Down Expand Up @@ -110,35 +110,18 @@ function verifyUserPublicKeyWithPrv(
}

/**
* TODO: Deprecate in favor of verifyUserPublicKeyAsync once v2 encryption is default.
* Decrypt the wallet's user private key and verify that the claimed public key matches (sync, v1 only).
* Decrypt the wallet's user private key and verify that the claimed public key matches.
* Supports both v1 (SJCL) and v2 (Argon2id) envelopes.
*/
export function verifyUserPublicKey(bitgo: BitGoBase, params: VerifyUserPublicKeyOptions): boolean {
export async function verifyUserPublicKey(bitgo: BitGoBase, params: VerifyUserPublicKeyOptions): Promise<boolean> {
const { userKeychain, txParams, disableNetworking } = params;
if (!userKeychain) {
throw new Error('user keychain is required');
}

let userPrv = userKeychain.prv;
if (!userPrv && txParams.walletPassphrase) {
userPrv = decryptKeychainPrivateKey(bitgo, userKeychain, txParams.walletPassphrase);
}

return verifyUserPublicKeyWithPrv(userKeychain, userPrv, disableNetworking);
}

/**
* Async version of verifyUserPublicKey with v2 encrypt/decrypt support.
*/
export async function verifyUserPublicKeyAsync(bitgo: BitGoBase, params: VerifyUserPublicKeyOptions): Promise<boolean> {
const { userKeychain, txParams, disableNetworking } = params;
if (!userKeychain) {
throw new Error('user keychain is required');
}

let userPrv = userKeychain.prv;
if (!userPrv && txParams.walletPassphrase) {
userPrv = await decryptKeychainPrivateKeyAsync(bitgo, userKeychain, txParams.walletPassphrase);
userPrv = await decryptKeychainPrivateKey(bitgo, userKeychain, txParams.walletPassphrase);
}

return verifyUserPublicKeyWithPrv(userKeychain, userPrv, disableNetworking);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ const keyDocumentObjects = rootWalletKeys.triple.map((bip32, keyIdx) => ({
id: getSeed(keychainsBase58[keyIdx].pub).toString('hex'),
pub: bip32.neutered().toBase58(),
source: ['user', 'backup', 'bitgo'][keyIdx],
encryptedPrv: encryptKeychain(walletPassphrase, keychainsBase58[keyIdx]),
encryptedPrv: '',
coinSpecific: {},
}));

Expand All @@ -43,7 +43,12 @@ describe('prebuildAndSign-returnLegacyFormat', function () {
let recipient: { address: string; amount: string };
const fee = BigInt(10000);

before(function () {
before(async function () {
await Promise.all(
keyDocumentObjects.map(async (doc, keyIdx) => {
doc.encryptedPrv = await encryptKeychain(walletPassphrase, keychainsBase58[keyIdx]);
})
);
const outputAmount = BigInt(inputScripts.length) * BigInt(1e8) - fee;
const outputScriptType: utxolib.bitgo.outputScripts.ScriptType = 'p2sh';
const outputChain = utxolib.bitgo.getExternalChainCode(outputScriptType);
Expand Down
12 changes: 6 additions & 6 deletions modules/abstract-utxo/test/unit/keychains.ts
Original file line number Diff line number Diff line change
Expand Up @@ -47,26 +47,26 @@ describe('Audit Key', function () {
});
});

it('should throw error if the walletPassphrase is incorrect', function () {
assert.throws(
it('should throw error if the walletPassphrase is incorrect', async function () {
await assert.rejects(
() =>
coin.assertIsValidKey({
encryptedPrv: btcBackupKey.key,
walletPassphrase: 'foo',
}),
{ message: "failed to decrypt prv: password error - ccm: tag doesn't match" }
{ message: 'failed to decrypt prv: incorrect password' }
);
});

it('should throw if the key is altered', function () {
it('should throw if the key is altered', async function () {
const alteredKey = btcBackupKey.key.replace(/[0-9]/g, '0');
assert.throws(
await assert.rejects(
() =>
coin.assertIsValidKey({
encryptedPrv: alteredKey,
walletPassphrase: 'kAm[EFQ6o=SxlcLFDw%,',
}),
{ message: 'failed to decrypt prv: json decrypt: invalid parameters' }
{ message: 'failed to decrypt prv: decrypt: ciphertext is not valid JSON' }
);
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -41,8 +41,8 @@ type NamedKeys = {
// Get default wasm wallet keys (xpubs, xprivs, and walletKeys)
const { walletKeys: wasmWalletKeys, xpubs, xprivs } = getDefaultWasmWalletKeys();

function getNamedKeys(keys: Triple<BIP32>, password: string): NamedKeys {
function encode(k: BIP32): string {
async function getNamedKeys(keys: Triple<BIP32>, password: string): Promise<NamedKeys> {
async function encode(k: BIP32): Promise<string> {
const base58 = k.toBase58();
// Check if it's a public key
const pubKeyMatch = keychainsBase58.find((kc) => kc.pub === base58);
Expand All @@ -57,17 +57,17 @@ function getNamedKeys(keys: Triple<BIP32>, password: string): NamedKeys {
return encryptKeychain(password, keyBase58);
}
return {
userKey: encode(keys[0]),
backupKey: encode(keys[1]),
bitgoKey: encode(keys[2]),
userKey: await encode(keys[0]),
backupKey: await encode(keys[1]),
bitgoKey: await encode(keys[2]),
};
}

function getKeysForFullSignedRecovery(password: string): NamedKeys {
function getKeysForFullSignedRecovery(password: string): Promise<NamedKeys> {
return getNamedKeys([xprivs[0], xprivs[1], xpubs[2]], password);
}

const keysFullSignedRecovery = getKeysForFullSignedRecovery(walletPassphrase);
let keysFullSignedRecovery: NamedKeys;

/**
* Tests for unspent gathering via backupKeyRecovery with MockRecoveryProvider.
Expand All @@ -77,6 +77,10 @@ const keysFullSignedRecovery = getKeysForFullSignedRecovery(walletPassphrase);
describe('Backup Key Recovery - Unspent Gathering', function () {
const defaultFeeRateSatB = 100;

before(async function () {
keysFullSignedRecovery = await getKeysForFullSignedRecovery(walletPassphrase);
});

getMinUtxoCoins().forEach((coin) => {
describe(`Unspent Gathering [${coin.getChain()}]`, function () {
const { walletKeys: externalWallet } = createWasmWalletKeys('external');
Expand Down
Loading
Loading