]> Git Repo - VerusCoin.git/commitdiff
Make RPC password resistant to timing attacks
authorGavin Andresen <[email protected]>
Thu, 8 Aug 2013 09:58:57 +0000 (19:58 +1000)
committerGavin Andresen <[email protected]>
Thu, 8 Aug 2013 09:58:57 +0000 (19:58 +1000)
Fixes issue#2838; this is a tweaked version of pull#2845 that
should not leak the length of the password and is more generic,
in case we run into other situations where we need
timing-attack-resistant comparisons.

src/bitcoinrpc.cpp
src/test/util_tests.cpp
src/util.h

index 7a3e6560abbd7d9c70fdc206aae9646dbc2d01bf..dfce9789a5bde4cfa05e14782cc292d18662f11f 100644 (file)
@@ -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);
 }
 
 //
index fd936517fd065af5db1cc1eb2fed870f934b7dab..abfd882655ef193877d459195717e270c3d5e568 100644 (file)
@@ -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()
index 9aea56440602de2bed5cdbc3529ec94aabeae28c..c9614d30557182f72cf3315ed06c6fb7e4cc7fdd 100644 (file)
@@ -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
  */
This page took 0.034725 seconds and 4 git commands to generate.