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

[TON]: Do not require password at TWStoredKeyUpdateAddress #3931

Merged
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
13 changes: 6 additions & 7 deletions include/TrustWalletCore/TWStoredKey.h
Original file line number Diff line number Diff line change
Expand Up @@ -295,16 +295,15 @@ TWData* _Nullable TWStoredKeyExportJSON(struct TWStoredKey* _Nonnull key);
TW_EXPORT_METHOD
bool TWStoredKeyFixAddresses(struct TWStoredKey* _Nonnull key, TWData* _Nonnull password);

/// Re-derives address and public key for the specified chain.
/// It can be used to update the address if the default address format for the given chain has been changed.
/// This method needs the encryption password to re-write address.
/// Re-derives address for the account(s) associated with the given coin.
/// This method can be used if address format has been changed.
/// In case of multiple accounts, all of them will be updated.
///
/// \param key Non-null pointer to a stored key
/// \param password Non-null block of data, password of the stored key
/// \param coin Coin type for which to update the address and public key
/// \return `false` if the password is incorrect or there is no data for the specified chain, true otherwise.
/// \param coin Account(s) coin type to be updated
/// \return `false` if there are no accounts associated with the given coin, true otherwise
TW_EXPORT_METHOD
bool TWStoredKeyUpdateAddress(struct TWStoredKey* _Nonnull key, TWData* _Nonnull password, enum TWCoinType coin);
bool TWStoredKeyUpdateAddress(struct TWStoredKey* _Nonnull key, enum TWCoinType coin);

/// Retrieve stored key encoding parameters, as JSON string.
///
Expand Down
33 changes: 13 additions & 20 deletions src/Keystore/StoredKey.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -292,29 +292,22 @@ void StoredKey::fixAddresses(const Data& password) {
}
}

bool StoredKey::updateAddress(TWCoinType coin, const Data& password) {
auto account = std::find_if(accounts.begin(), accounts.end(), [coin](const auto &account) {
return account.coin == coin;
});
if (account == accounts.end()) {
return false;
}
bool StoredKey::updateAddress(TWCoinType coin) {
bool addressUpdated = false;
const auto publicKeyType = TW::publicKeyType(coin);

switch (type) {
case StoredKeyType::mnemonicPhrase: {
const auto wallet = this->wallet(password);
const auto& derivationPath = account->derivationPath;
const auto key = wallet.getKey(account->coin, derivationPath);
updateAddressForAccount(key, *account);
} break;

case StoredKeyType::privateKey: {
auto key = PrivateKey(payload.decrypt(password));
updateAddressForAccount(key, *account);
} break;
for (auto& account : accounts) {
// Update the address for the given chain if only `publicKey` is set.
if (account.coin == coin && !account.publicKey.empty()) {
const auto publicKeyBytes = parse_hex(account.publicKey);
const PublicKey publicKey(publicKeyBytes, publicKeyType);
account.address = TW::deriveAddress(account.coin, publicKey, account.derivation);

addressUpdated = true;
}
}

return true;
return addressUpdated;
}

// -----------------
Expand Down
8 changes: 4 additions & 4 deletions src/Keystore/StoredKey.h
Original file line number Diff line number Diff line change
Expand Up @@ -144,11 +144,11 @@ class StoredKey {
/// the encryption password to re-derive addresses from private keys.
void fixAddresses(const Data& password);

/// Re-derives address and public key for the specified chain.
/// Re-derives address for the account(s) associated with the given coin.
///
/// Use when address format for the given chain has been changed. This method needs
/// the encryption password to re-derive addresses from private keys.
bool updateAddress(TWCoinType coin, const Data& password);
/// This method can be used if address format has been changed.
/// In case of multiple accounts, all of them will be updated.
bool updateAddress(TWCoinType coin);

private:
/// Default constructor, private
Expand Down
5 changes: 2 additions & 3 deletions src/interface/TWStoredKey.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -224,10 +224,9 @@ bool TWStoredKeyFixAddresses(struct TWStoredKey* _Nonnull key, TWData* _Nonnull
}
}

bool TWStoredKeyUpdateAddress(struct TWStoredKey* _Nonnull key, TWData* _Nonnull password, enum TWCoinType coin) {
bool TWStoredKeyUpdateAddress(struct TWStoredKey* _Nonnull key, enum TWCoinType coin) {
try {
const auto passwordData = TW::data(TWDataBytes(password), TWDataSize(password));
return key->impl.updateAddress(coin, passwordData);
return key->impl.updateAddress(coin);
} catch (...) {
return false;
}
Expand Down
19 changes: 4 additions & 15 deletions tests/interface/TWStoredKeyTests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -305,7 +305,7 @@ TEST(TWStoredKey, UpdateAddressWithMnemonic) {

// Last step - update TON account address.
// Expect to have a non-bounceable address in the end.
ASSERT_TRUE(TWStoredKeyUpdateAddress(key.get(), password.get(), TWCoinTypeTON));
ASSERT_TRUE(TWStoredKeyUpdateAddress(key.get(), TWCoinTypeTON));
const auto tonAccount = WRAP(TWAccount, TWStoredKeyAccountForCoin(key.get(), TWCoinTypeTON, nullptr));
assertStringsEqual(WRAPS(TWAccountAddress(tonAccount.get())), newAddress);
}
Expand Down Expand Up @@ -338,29 +338,18 @@ TEST(TWStoredKey, UpdateAddressWithPrivateKey) {

// Last step - update Ethereum account address.
// Expect to have a checksummed address in the end.
ASSERT_TRUE(TWStoredKeyUpdateAddress(key.get(), password.get(), TWCoinTypeEthereum));
ASSERT_TRUE(TWStoredKeyUpdateAddress(key.get(), TWCoinTypeEthereum));
const auto ethAccount = WRAP(TWAccount, TWStoredKeyAccountForCoin(key.get(), TWCoinTypeEthereum, nullptr));
assertStringsEqual(WRAPS(TWAccountAddress(ethAccount.get())), newAddress);
}

TEST(TWStoredKey, updateAddressInvalidPassword) {
TEST(TWStoredKey, updateAddressNoAssociatedAccounts) {
const auto keyName = STRING("key");
const string passwordString = "password";
const string invalidPasswordString = "invalid password";
const auto password = WRAPD(TWDataCreateWithBytes((const uint8_t*)passwordString.c_str(), passwordString.size()));
const auto invalidPassword = WRAPD(TWDataCreateWithBytes((const uint8_t*)invalidPasswordString.c_str(), invalidPasswordString.size()));

auto key = createAStoredKey(TWCoinTypeBitcoin, password.get());
ASSERT_FALSE(TWStoredKeyUpdateAddress(key.get(), invalidPassword.get(), TWCoinTypeBitcoin));
}

TEST(TWStoredKey, updateAddressUnknownAccount) {
const auto keyName = STRING("key");
const string passwordString = "password";
const auto password = WRAPD(TWDataCreateWithBytes((const uint8_t*)passwordString.c_str(), passwordString.size()));

auto key = createAStoredKey(TWCoinTypeBitcoin, password.get());
ASSERT_FALSE(TWStoredKeyUpdateAddress(key.get(), password.get(), TWCoinTypeEthereum));
ASSERT_FALSE(TWStoredKeyUpdateAddress(key.get(), TWCoinTypeEthereum));
}

TEST(TWStoredKey, importInvalidKey) {
Expand Down
Loading