Skip to content

Commit b5cf554

Browse files
fix(starkware): Update TWStarkWareGetStarkKeyFromSignature to return nullable pointer and handle exceptions (#4715)
* fix(starkware): Update TWStarkWareGetStarkKeyFromSignature to return nullable pointer and handle exceptions * Update include/TrustWalletCore/TWStarkWare.h Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> * fix(tezos): Enhance message verification to handle exceptions gracefully * fix(address): Handle empty payload case in Address constructor and improve subData error handling * fix(data): Include stdexcept to fix Flutter compilation --------- Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
1 parent 6d4549a commit b5cf554

File tree

8 files changed

+43
-12
lines changed

8 files changed

+43
-12
lines changed

include/TrustWalletCore/TWStarkWare.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,8 @@ struct TWStarkWare;
1818
///
1919
/// \param derivationPath non-null StarkEx Derivation path
2020
/// \param signature valid eth signature
21-
/// \return The private key for the specified derivation path/signature
21+
/// \return The private key for the specified derivation path/signature, or `nullptr` if the signature or derivation path is invalid or an internal error occurs.
2222
TW_EXPORT_STATIC_METHOD
23-
struct TWPrivateKey* _Nonnull TWStarkWareGetStarkKeyFromSignature(const struct TWDerivationPath* _Nonnull derivationPath, TWString* _Nonnull signature);
23+
struct TWPrivateKey* _Nullable TWStarkWareGetStarkKeyFromSignature(const struct TWDerivationPath* _Nonnull derivationPath, TWString* _Nonnull signature);
2424

2525
TW_EXTERN_C_END

src/Data.cpp

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,19 +4,21 @@
44

55
#include "Data.h"
66

7+
#include <stdexcept>
8+
79
namespace TW {
810

911
Data subData(const Data& data, size_t startIndex, size_t length) {
1012
if (startIndex >= data.size()) {
11-
return Data();
13+
throw std::invalid_argument("invalid subData arguments");
1214
}
1315
const size_t subLength = std::min(length, data.size() - startIndex); // guard against over-length
1416
return TW::data(data.data() + startIndex, subLength);
1517
}
1618

1719
Data subData(const Data& data, size_t startIndex) {
1820
if (startIndex >= data.size()) {
19-
return Data();
21+
throw std::invalid_argument("invalid subData arguments");
2022
}
2123
const size_t subLength = data.size() - startIndex;
2224
return TW::data(data.data() + startIndex, subLength);

src/Filecoin/Address.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -144,6 +144,10 @@ MaybeAddress Address::fromBytes(const Data& encoded) {
144144
return std::nullopt;
145145
}
146146

147+
if (remainingPos == withoutPrefix.size()) {
148+
// Payload is empty.
149+
return Address(type, actorID, Data());
150+
}
147151
return Address(type, actorID, subData(withoutPrefix, remainingPos));
148152
}
149153
default:

src/HDWallet.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,9 @@ const int MnemonicBufLength = Mnemonic::MaxWords * (BIP39_MAX_WORD_LENGTH + 3) +
4040

4141
template <std::size_t seedSize>
4242
HDWallet<seedSize>::HDWallet(const Data& seed) {
43+
if (seed.size() != seedSize) {
44+
throw std::invalid_argument("Invalid seed size");
45+
}
4346
std::copy_n(seed.begin(), seedSize, this->seed.begin());
4447
}
4548

src/Tezos/MessageSigner.cpp

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -44,9 +44,13 @@ std::string MessageSigner::signMessage(const PrivateKey& privateKey, const std::
4444

4545
bool MessageSigner::verifyMessage(const PublicKey& publicKey, const std::string& message, const std::string& signature) noexcept {
4646
auto decoded = Base58::decodeCheck(signature);
47-
auto rawSignature = subData(decoded, gEdSigPrefix.size());
48-
auto msg = Hash::blake2b(parse_hex(message), 32);
49-
return publicKey.verify(rawSignature, msg);
47+
try {
48+
auto rawSignature = subData(decoded, gEdSigPrefix.size());
49+
auto msg = Hash::blake2b(parse_hex(message), 32);
50+
return publicKey.verify(rawSignature, msg);
51+
} catch (...) {
52+
return false;
53+
}
5054
}
5155

5256
} // namespace TW::Tezos

src/interface/TWStarkWare.cpp

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,5 +11,9 @@
1111
struct TWPrivateKey* TWStarkWareGetStarkKeyFromSignature(const struct TWDerivationPath* derivationPath, TWString* signature) {
1212
using namespace TW;
1313
const auto& ethSignatureStr = *reinterpret_cast<const std::string*>(signature);
14-
return new TWPrivateKey{ ImmutableX::getPrivateKeyFromRawSignature(parse_hex(ethSignatureStr), derivationPath->impl)};
14+
try {
15+
return new TWPrivateKey{ ImmutableX::getPrivateKeyFromRawSignature(parse_hex(ethSignatureStr), derivationPath->impl)};
16+
} catch (...) {
17+
return nullptr;
18+
}
1519
}

swift/Tests/HDWalletTests.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ class HDWalletTests: XCTestCase {
2727
let ethMsg = "Only sign this request if you’ve initiated an action with Immutable X."
2828
let ethSignature = EthereumMessageSigner.signMessageImmutableX(privateKey: ethPrivateKey, message: ethMsg)
2929
XCTAssertEqual(ethSignature, "18b1be8b78807d3326e28bc286d7ee3d068dcd90b1949ce1d25c1f99825f26e70992c5eb7f44f76b202aceded00d74f771ed751f2fe538eec01e338164914fe001")
30-
let starkPrivateKey = StarkWare.getStarkKeyFromSignature(derivationPath: derivationPath, signature: ethSignature)
30+
let starkPrivateKey = StarkWare.getStarkKeyFromSignature(derivationPath: derivationPath, signature: ethSignature)!
3131
XCTAssertEqual(starkPrivateKey.data.hexString, "04be51a04e718c202e4dca60c2b72958252024cfc1070c090dd0f170298249de")
3232
let starkPublicKey = starkPrivateKey.getPublicKeyByType(pubkeyType: .starkex)
3333
XCTAssertEqual(starkPublicKey.data.hexString, "00e5b9b11f8372610ef35d647a1dcaba1a4010716588d591189b27bf3c2d5095")

tests/common/DataTests.cpp

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -66,13 +66,27 @@ TEST(DataTests, subData) {
6666
EXPECT_EQ(hex(subData(data, 0, 10)), "0102030405060708090a");
6767
EXPECT_EQ(hex(subData(data, 3, 1)), "04");
6868
EXPECT_EQ(hex(subData(data, 3, 0)), "");
69-
EXPECT_EQ(hex(subData(data, 200, 3)), ""); // index too big
7069
EXPECT_EQ(hex(subData(data, 2, 300)), "030405060708090a"); // length too big
71-
EXPECT_EQ(hex(subData(data, 200, 300)), ""); // index & length too big
7270

7371
EXPECT_EQ(hex(subData(data, 3)), "0405060708090a");
7472
EXPECT_EQ(hex(subData(data, 0)), "0102030405060708090a");
75-
EXPECT_EQ(hex(subData(data, 200)), ""); // index too big
73+
74+
// index too big
75+
ASSERT_ANY_THROW(subData(data, 10, 3));
76+
ASSERT_ANY_THROW(subData(data, 11, 1));
77+
ASSERT_ANY_THROW(subData(data, 200, 300));
78+
79+
ASSERT_ANY_THROW(subData(data, 10ul));
80+
ASSERT_ANY_THROW(subData(data, 11ul));
81+
ASSERT_ANY_THROW(subData(data, 200ul));
82+
}
83+
84+
TEST(DataTests, subDataInvalidStartIndex) {
85+
const Data data = parse_hex("0102030405060708090a");
86+
EXPECT_EQ(data.size(), 10ul);
87+
ASSERT_ANY_THROW(subData(data, 10ul));
88+
ASSERT_ANY_THROW(subData(data, 11ul));
89+
ASSERT_ANY_THROW(subData(data, 200ul));
7690
}
7791

7892
TEST(DataTests, hasPrefix) {

0 commit comments

Comments
 (0)