Address issues identified by external review:

* RIPD-1617, RIPD-1619, RIPD-1621:
  Verify serialized public keys more strictly before
  using them.

* RIPD-1618:
    * Simplify the base58 decoder logic.
    * Reduce the complexity of the base58 encoder and
      eliminate a potential out-of-bounds memory access.
    * Improve type safety by using an `enum class` to
      enforce strict type checking for token types.

* RIPD-1616:
  Avoid calling `memcpy` with a null pointer even if the
  size is specified as zero, since it results in undefined
  behavior.

Acknowledgements:
Ripple thanks Guido Vranken for responsibly disclosing these
issues.

Bug Bounties and Responsible Disclosures:
We welcome reviews of the rippled code and urge researchers
to responsibly disclose any issues that they may find. For
more on Ripple's Bug Bounty program, please visit:
https://ripple.com/bug-bounty
This commit is contained in:
Nikolaos D. Bougalis
2018-03-15 20:58:05 -07:00
parent 25de6b0a5f
commit d5f981f5fc
47 changed files with 393 additions and 264 deletions

View File

@@ -320,7 +320,7 @@ public:
generateSeed ("masterpassphrase"));
auto const sk2 = parseBase58<SecretKey> (
TOKEN_NODE_PRIVATE,
TokenType::NodePrivate,
"pnen77YEeUd4fFKG7iycBWcwKpTaeFRkW2WFostaATy1DSupwXe");
BEAST_EXPECT(sk2);
@@ -333,7 +333,7 @@ public:
generateSeed ("masterpassphrase"));
auto const sk2 = parseBase58<SecretKey> (
TOKEN_NODE_PRIVATE,
TokenType::NodePrivate,
"paKv46LztLqK3GaKz1rG2nQGN6M4JLyRtxFBYFTw4wAVHtGys36");
BEAST_EXPECT(sk2);
@@ -341,12 +341,12 @@ public:
}
// Try converting short, long and malformed data
BEAST_EXPECT(!parseBase58<SecretKey> (TOKEN_NODE_PRIVATE, ""));
BEAST_EXPECT(!parseBase58<SecretKey> (TOKEN_NODE_PRIVATE, " "));
BEAST_EXPECT(!parseBase58<SecretKey> (TOKEN_NODE_PRIVATE, "!35gty9mhju8nfjl"));
BEAST_EXPECT(!parseBase58<SecretKey> (TokenType::NodePrivate, ""));
BEAST_EXPECT(!parseBase58<SecretKey> (TokenType::NodePrivate, " "));
BEAST_EXPECT(!parseBase58<SecretKey> (TokenType::NodePrivate, "!35gty9mhju8nfjl"));
auto const good = toBase58 (
TokenType::TOKEN_NODE_PRIVATE,
TokenType::NodePrivate,
randomSecretKey());
// Short (non-empty) strings
@@ -359,7 +359,7 @@ public:
while (!s.empty())
{
s.erase (r(s) % s.size(), 1);
BEAST_EXPECT(!parseBase58<SecretKey> (TOKEN_NODE_PRIVATE, s));
BEAST_EXPECT(!parseBase58<SecretKey> (TokenType::NodePrivate, s));
}
}
@@ -368,7 +368,7 @@ public:
{
auto s = good;
s.resize (s.size() + i, s[i % s.size()]);
BEAST_EXPECT(!parseBase58<SecretKey> (TOKEN_NODE_PRIVATE, s));
BEAST_EXPECT(!parseBase58<SecretKey> (TokenType::NodePrivate, s));
}
// Strings with invalid Base58 characters
@@ -378,7 +378,7 @@ public:
{
auto s = good;
s[i % s.size()] = c;
BEAST_EXPECT(!parseBase58<SecretKey> (TOKEN_NODE_PRIVATE, s));
BEAST_EXPECT(!parseBase58<SecretKey> (TokenType::NodePrivate, s));
}
}
@@ -389,7 +389,7 @@ public:
for (auto c : std::string("ansrJqtv7"))
{
s[0] = c;
BEAST_EXPECT(!parseBase58<SecretKey> (TOKEN_NODE_PRIVATE, s));
BEAST_EXPECT(!parseBase58<SecretKey> (TokenType::NodePrivate, s));
}
}
@@ -402,12 +402,12 @@ public:
for (std::size_t i = 0; i != keys.size(); ++i)
{
auto const si = toBase58 (
TokenType::TOKEN_NODE_PRIVATE,
TokenType::NodePrivate,
keys[i]);
BEAST_EXPECT(!si.empty());
auto const ski = parseBase58<SecretKey> (
TOKEN_NODE_PRIVATE, si);
TokenType::NodePrivate, si);
BEAST_EXPECT(ski && keys[i] == *ski);
for (std::size_t j = i; j != keys.size(); ++j)
@@ -415,13 +415,13 @@ public:
BEAST_EXPECT((keys[i] == keys[j]) == (i == j));
auto const sj = toBase58 (
TokenType::TOKEN_NODE_PRIVATE,
TokenType::NodePrivate,
keys[j]);
BEAST_EXPECT((si == sj) == (i == j));
auto const skj = parseBase58<SecretKey> (
TOKEN_NODE_PRIVATE, sj);
TokenType::NodePrivate, sj);
BEAST_EXPECT(skj && keys[j] == *skj);
BEAST_EXPECT((*ski == *skj) == (i == j));