aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGavin Andresen <gavinandresen@gmail.com>2013-08-15 18:53:26 -0700
committerGavin Andresen <gavinandresen@gmail.com>2013-08-15 18:53:26 -0700
commita0bb0014312a558432a5192540f4a6c796559ea0 (patch)
treeb195096cdb4cda507f7b818208fada62e0537378
parent9be4cff5f683d8d4b151a76c598e22e22ba63049 (diff)
parent42656ea2e552b027e174fdceab7348ffcb8245c4 (diff)
Merge pull request #2886 from gavinandresen/rpctiming
Make RPC password resistant to timing attacks
-rw-r--r--src/bitcoinrpc.cpp2
-rw-r--r--src/test/util_tests.cpp11
-rw-r--r--src/util.h15
3 files changed, 27 insertions, 1 deletions
diff --git a/src/bitcoinrpc.cpp b/src/bitcoinrpc.cpp
index a14f5e7060..d22809ce69 100644
--- a/src/bitcoinrpc.cpp
+++ b/src/bitcoinrpc.cpp
@@ -476,7 +476,7 @@ bool HTTPAuthorized(map<string, string>& mapHeaders)
return false;
string strUserPass64 = strAuth.substr(6); boost::trim(strUserPass64);
string strUserPass = DecodeBase64(strUserPass64);
- return strUserPass == strRPCUserColonPass;
+ return TimingResistantEqual(strUserPass, strRPCUserColonPass);
}
//
diff --git a/src/test/util_tests.cpp b/src/test/util_tests.cpp
index fd936517fd..abfd882655 100644
--- a/src/test/util_tests.cpp
+++ b/src/test/util_tests.cpp
@@ -291,4 +291,15 @@ BOOST_AUTO_TEST_CASE(util_seed_insecure_rand)
}
}
+BOOST_AUTO_TEST_CASE(util_TimingResistantEqual)
+{
+ BOOST_CHECK(TimingResistantEqual(std::string(""), std::string("")));
+ BOOST_CHECK(!TimingResistantEqual(std::string("abc"), std::string("")));
+ BOOST_CHECK(!TimingResistantEqual(std::string(""), std::string("abc")));
+ BOOST_CHECK(!TimingResistantEqual(std::string("a"), std::string("aa")));
+ BOOST_CHECK(!TimingResistantEqual(std::string("aa"), std::string("a")));
+ BOOST_CHECK(TimingResistantEqual(std::string("abc"), std::string("abc")));
+ BOOST_CHECK(!TimingResistantEqual(std::string("abc"), std::string("aba")));
+}
+
BOOST_AUTO_TEST_SUITE_END()
diff --git a/src/util.h b/src/util.h
index 9aea564406..c9614d3055 100644
--- a/src/util.h
+++ b/src/util.h
@@ -437,6 +437,21 @@ static inline uint32_t insecure_rand(void)
*/
void seed_insecure_rand(bool fDeterministic=false);
+/**
+ * Timing-attack-resistant comparison.
+ * Takes time proportional to length
+ * of first argument.
+ */
+template <typename T>
+bool TimingResistantEqual(const T& a, const T& b)
+{
+ if (b.size() == 0) return a.size() == 0;
+ size_t accumulator = a.size() ^ b.size();
+ for (size_t i = 0; i < a.size(); i++)
+ accumulator |= a[i] ^ b[i%b.size()];
+ return accumulator == 0;
+}
+
/** Median filter over a stream of values.
* Returns the median of the last N numbers
*/