aboutsummaryrefslogtreecommitdiff
path: root/src/base58.cpp
diff options
context:
space:
mode:
authorWladimir J. van der Laan <laanwj@protonmail.com>2019-12-12 10:55:37 +0100
committerWladimir J. van der Laan <laanwj@protonmail.com>2019-12-12 10:56:31 +0100
commit3914e877c476f4e83816f4bf2e4c68f0fac181b8 (patch)
treec750ed28993b90b69c3e974785b820e8c31cd5fd /src/base58.cpp
parent3f1966ead6b2324d863ae6c5d9956cf4b9e4b148 (diff)
parent5909bcd3bf3c3502355e89fd0b76bb8e93d8a95b (diff)
downloadbitcoin-3914e877c476f4e83816f4bf2e4c68f0fac181b8.tar.xz
Merge #17511: Add bounds checks before base58 decoding
5909bcd3bf3c3502355e89fd0b76bb8e93d8a95b Add bounds checks in key_io before DecodeBase58Check (Pieter Wuille) 2bcf1fc444d5c4b8efa879e54e7b6134b7e6b986 Pass a maximum output length to DecodeBase58 and DecodeBase58Check (Pieter Wuille) Pull request description: Fixes #17501. ACKs for top commit: laanwj: code review ACK 5909bcd3bf3c3502355e89fd0b76bb8e93d8a95b practicalswift: ACK 5909bcd3bf3c3502355e89fd0b76bb8e93d8a95b -- code looks correct Tree-SHA512: 4807f4a9508dee9c0f1ad63f56f70f4ec4e6b7e35eb91322a525e3da3828521a41de9b8338a6bf67250803660b480d95fd02ce6b2fe79c4c88bc19b54f9d8889
Diffstat (limited to 'src/base58.cpp')
-rw-r--r--src/base58.cpp20
1 files changed, 11 insertions, 9 deletions
diff --git a/src/base58.cpp b/src/base58.cpp
index e3d2853399..a0149fb641 100644
--- a/src/base58.cpp
+++ b/src/base58.cpp
@@ -11,6 +11,8 @@
#include <assert.h>
#include <string.h>
+#include <limits>
+
/** All alphanumeric characters except for "0", "I", "O", and "l" */
static const char* pszBase58 = "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz";
static const int8_t mapBase58[256] = {
@@ -32,7 +34,7 @@ static const int8_t mapBase58[256] = {
-1,-1,-1,-1,-1,-1,-1,-1, -1,-1,-1,-1,-1,-1,-1,-1,
};
-bool DecodeBase58(const char* psz, std::vector<unsigned char>& vch)
+bool DecodeBase58(const char* psz, std::vector<unsigned char>& vch, int max_ret_len)
{
// Skip leading spaces.
while (*psz && IsSpace(*psz))
@@ -42,6 +44,7 @@ bool DecodeBase58(const char* psz, std::vector<unsigned char>& vch)
int length = 0;
while (*psz == '1') {
zeroes++;
+ if (zeroes > max_ret_len) return false;
psz++;
}
// Allocate enough space in big-endian base256 representation.
@@ -62,6 +65,7 @@ bool DecodeBase58(const char* psz, std::vector<unsigned char>& vch)
}
assert(carry == 0);
length = i;
+ if (length + zeroes > max_ret_len) return false;
psz++;
}
// Skip trailing spaces.
@@ -71,8 +75,6 @@ bool DecodeBase58(const char* psz, std::vector<unsigned char>& vch)
return false;
// Skip leading zeroes in b256.
std::vector<unsigned char>::iterator it = b256.begin() + (size - length);
- while (it != b256.end() && *it == 0)
- it++;
// Copy result into output vector.
vch.reserve(zeroes + (b256.end() - it));
vch.assign(zeroes, 0x00);
@@ -126,9 +128,9 @@ std::string EncodeBase58(const std::vector<unsigned char>& vch)
return EncodeBase58(vch.data(), vch.data() + vch.size());
}
-bool DecodeBase58(const std::string& str, std::vector<unsigned char>& vchRet)
+bool DecodeBase58(const std::string& str, std::vector<unsigned char>& vchRet, int max_ret_len)
{
- return DecodeBase58(str.c_str(), vchRet);
+ return DecodeBase58(str.c_str(), vchRet, max_ret_len);
}
std::string EncodeBase58Check(const std::vector<unsigned char>& vchIn)
@@ -140,9 +142,9 @@ std::string EncodeBase58Check(const std::vector<unsigned char>& vchIn)
return EncodeBase58(vch);
}
-bool DecodeBase58Check(const char* psz, std::vector<unsigned char>& vchRet)
+bool DecodeBase58Check(const char* psz, std::vector<unsigned char>& vchRet, int max_ret_len)
{
- if (!DecodeBase58(psz, vchRet) ||
+ if (!DecodeBase58(psz, vchRet, max_ret_len > std::numeric_limits<int>::max() - 4 ? std::numeric_limits<int>::max() : max_ret_len + 4) ||
(vchRet.size() < 4)) {
vchRet.clear();
return false;
@@ -157,7 +159,7 @@ bool DecodeBase58Check(const char* psz, std::vector<unsigned char>& vchRet)
return true;
}
-bool DecodeBase58Check(const std::string& str, std::vector<unsigned char>& vchRet)
+bool DecodeBase58Check(const std::string& str, std::vector<unsigned char>& vchRet, int max_ret)
{
- return DecodeBase58Check(str.c_str(), vchRet);
+ return DecodeBase58Check(str.c_str(), vchRet, max_ret);
}