Skip to content

Commit 5668c67

Browse files
fix(public-key): Fix PublicKey::verify by adding signature length validation (#4565)
* fix(public-key): Fix `PublicKey::verify` by adding signature length validation * fix(public-key): Fix PR comments
1 parent 5afbb3e commit 5668c67

File tree

2 files changed

+36
-0
lines changed

2 files changed

+36
-0
lines changed

src/PublicKey.cpp

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,26 @@
2020

2121
namespace TW {
2222

23+
bool validateSignatureLength(TWPublicKeyType type, const Data& signature) {
24+
std::size_t minLength = 64;
25+
std::size_t maxLength = 64;
26+
27+
switch (type) {
28+
case TWPublicKeyTypeSECP256k1:
29+
case TWPublicKeyTypeSECP256k1Extended:
30+
case TWPublicKeyTypeNIST256p1:
31+
case TWPublicKeyTypeNIST256p1Extended: {
32+
maxLength = 65;
33+
break;
34+
}
35+
default: {
36+
break;
37+
}
38+
}
39+
40+
return minLength <= signature.size() && signature.size() <= maxLength;
41+
}
42+
2343
/// Determines if a collection of bytes makes a valid public key of the
2444
/// given type.
2545
bool PublicKey::isValid(const Data& data, enum TWPublicKeyType type) {
@@ -142,6 +162,10 @@ bool rust_public_key_verify(const Data& key, TWPublicKeyType type, const Data& s
142162
}
143163

144164
bool PublicKey::verify(const Data& signature, const Data& message) const {
165+
if (!validateSignatureLength(type, signature)) {
166+
return false;
167+
}
168+
145169
switch (type) {
146170
case TWPublicKeyTypeSECP256k1:
147171
case TWPublicKeyTypeSECP256k1Extended:

tests/interface/TWPublicKeyTests.cpp

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,18 @@ TEST(TWPublicKeyTests, Verify) {
7979
ASSERT_TRUE(TWPublicKeyVerify(publicKey.get(), signature.get(), digest.get()));
8080
}
8181

82+
TEST(TWPublicKeyTests, VerifyInvalidLength) {
83+
const PrivateKey key(parse_hex("afeefca74d9a325cf1d6b6911d61a65c32afa8e02bd5e78e2e4ac2910bab45f5"), TWCurveSECP256k1);
84+
const auto privateKey = WRAP(TWPrivateKey, new TWPrivateKey{ key });
85+
86+
const auto message = DATA("de4e9524586d6fce45667f9ff12f661e79870c4105fa0fb58af976619bb11432");
87+
// 63 bytes instead of 64 or 65.
88+
const auto signature = DATA("0000000000000000000000000000000000000000000000000000000000020123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef80");
89+
90+
auto publicKey = WRAP(TWPublicKey, TWPrivateKeyGetPublicKeySecp256k1(privateKey.get(), false));
91+
ASSERT_FALSE(TWPublicKeyVerify(publicKey.get(), signature.get(), message.get()));
92+
}
93+
8294
TEST(TWPublicKeyTests, VerifyAsDER) {
8395
const PrivateKey key = PrivateKey(parse_hex("afeefca74d9a325cf1d6b6911d61a65c32afa8e02bd5e78e2e4ac2910bab45f5"), TWCurveSECP256k1);
8496
const auto privateKey = WRAP(TWPrivateKey, new TWPrivateKey{ key });

0 commit comments

Comments
 (0)