diff --git a/src/test/bip32_tests.cpp b/src/test/bip32_tests.cpp index 3f13cd6ebe9..daa03a6679b 100644 --- a/src/test/bip32_tests.cpp +++ b/src/test/bip32_tests.cpp @@ -265,8 +265,12 @@ BOOST_AUTO_TEST_CASE(parse_hd_keypath) BOOST_CHECK(ParseHDKeypath("42", keypath)); BOOST_CHECK(!ParseHDKeypath("m42", keypath)); - BOOST_CHECK(ParseHDKeypath("4294967295", keypath)); // 4294967295 == 0xFFFFFFFF (uint32_t max) - BOOST_CHECK(!ParseHDKeypath("4294967296", keypath)); // 4294967296 == 0xFFFFFFFF (uint32_t max) + 1 + // A path element's numeric part is capped at 2^31-1; the top bit is + // reserved for the hardened marker (h or '). + BOOST_CHECK(ParseHDKeypath("2147483647", keypath)); // 0x7fffffff, largest normal index + BOOST_CHECK(!ParseHDKeypath("2147483648", keypath)); // 0x80000000, would set the hardened bit + BOOST_CHECK(!ParseHDKeypath("4294967295", keypath)); // 0xffffffff + BOOST_CHECK(!ParseHDKeypath("4294967296", keypath)); // uint32_t max + 1 BOOST_CHECK(ParseHDKeypath("m", keypath)); BOOST_CHECK(!ParseHDKeypath("n", keypath)); @@ -306,12 +310,6 @@ BOOST_AUTO_TEST_CASE(parse_hd_keypath) BOOST_CHECK(ParseHDKeypath("m/1/", keypath)); BOOST_CHECK(!ParseHDKeypath("m/1//", keypath)); - - BOOST_CHECK(ParseHDKeypath("m/0/4294967295", keypath)); // 4294967295 == 0xFFFFFFFF (uint32_t max) - BOOST_CHECK(!ParseHDKeypath("m/0/4294967296", keypath)); // 4294967296 == 0xFFFFFFFF (uint32_t max) + 1 - - BOOST_CHECK(ParseHDKeypath("m/4294967295", keypath)); // 4294967295 == 0xFFFFFFFF (uint32_t max) - BOOST_CHECK(!ParseHDKeypath("m/4294967296", keypath)); // 4294967296 == 0xFFFFFFFF (uint32_t max) + 1 } BOOST_AUTO_TEST_SUITE_END() diff --git a/src/util/bip32.cpp b/src/util/bip32.cpp index 5f0ca221f52..475fac60a46 100644 --- a/src/util/bip32.cpp +++ b/src/util/bip32.cpp @@ -45,6 +45,11 @@ bool ParseHDKeypath(const std::string& keypath_str, std::vector& keypa if (!number) { return false; } + // A BIP32 child index is 31 bits; the top bit is reserved for the + // hardened marker, so the numeric part must not exceed 2^31 - 1. + if (*number > 0x7fffffff) { + return false; + } path |= *number; keypath.push_back(path);