Skip to content

Commit fb9faff

Browse files
committed
extended keys: fail to derive too large depth instead of wrapping around
This issue was reported to me by Marco Falke, and found with the descriptor_parse fuzz target.
1 parent 8dc6670 commit fb9faff

File tree

3 files changed

+20
-0
lines changed

3 files changed

+20
-0
lines changed

src/key.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -333,6 +333,7 @@ bool CKey::Derive(CKey& keyChild, ChainCode &ccChild, unsigned int nChild, const
333333
}
334334

335335
bool CExtKey::Derive(CExtKey &out, unsigned int _nChild) const {
336+
if (nDepth == std::numeric_limits<unsigned char>::max()) return false;
336337
out.nDepth = nDepth + 1;
337338
CKeyID id = key.GetPubKey().GetID();
338339
memcpy(out.vchFingerprint, &id, 4);

src/pubkey.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -365,6 +365,7 @@ void CExtPubKey::DecodeWithVersion(const unsigned char code[BIP32_EXTKEY_WITH_VE
365365
}
366366

367367
bool CExtPubKey::Derive(CExtPubKey &out, unsigned int _nChild) const {
368+
if (nDepth == std::numeric_limits<unsigned char>::max()) return false;
368369
out.nDepth = nDepth + 1;
369370
CKeyID id = pubkey.GetID();
370371
memcpy(out.vchFingerprint, &id, 4);

src/test/bip32_tests.cpp

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -184,4 +184,22 @@ BOOST_AUTO_TEST_CASE(bip32_test5) {
184184
}
185185
}
186186

187+
BOOST_AUTO_TEST_CASE(bip32_max_depth) {
188+
CExtKey key_parent{DecodeExtKey(test1.vDerive[0].prv)}, key_child;
189+
CExtPubKey pubkey_parent{DecodeExtPubKey(test1.vDerive[0].pub)}, pubkey_child;
190+
191+
// We can derive up to the 255th depth..
192+
for (auto i = 0; i++ < 255;) {
193+
BOOST_CHECK(key_parent.Derive(key_child, 0));
194+
std::swap(key_parent, key_child);
195+
BOOST_CHECK(pubkey_parent.Derive(pubkey_child, 0));
196+
std::swap(pubkey_parent, pubkey_child);
197+
}
198+
199+
// But trying to derive a non-existent 256th depth will fail!
200+
BOOST_CHECK(key_parent.nDepth == 255 && pubkey_parent.nDepth == 255);
201+
BOOST_CHECK(!key_parent.Derive(key_child, 0));
202+
BOOST_CHECK(!pubkey_parent.Derive(pubkey_child, 0));
203+
}
204+
187205
BOOST_AUTO_TEST_SUITE_END()

0 commit comments

Comments
 (0)