From 6511bd83b46b2e14c5d08c682f1490b8816588a7 Mon Sep 17 00:00:00 2001 From: alex Date: Sat, 24 Aug 2013 18:21:53 +0400 Subject: [PATCH] Mitigate Timing Attacks On Basic RPC Authorization Eliminates the possibility of timing attacks by changing the way the two passwords are compared. It iterates through each char in the strings, and if the two chars it is comparing aren't the same, then it adds 1 to nReturn and the function, once it's done comparing all the chars, will return false. Previously, the function would return false on the first char that didn't match, allowing a possible attacker to run a timing attack. See https://github.com/bitcoin/bitcoin/pull/2886 http://rdist.root.org/2010/01/07/timing-independent-array-comparison/ for more detailed explanation. --- src/bitcoinrpc.cpp | 2 +- src/util.h | 14 ++++++++++++++ 2 files changed, 15 insertions(+), 1 deletions(-) diff --git a/src/bitcoinrpc.cpp b/src/bitcoinrpc.cpp index d9ed3ac..645fa97 100644 --- a/src/bitcoinrpc.cpp +++ b/src/bitcoinrpc.cpp @@ -490,7 +490,7 @@ bool HTTPAuthorized(map& 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/util.h b/src/util.h index 83a4012..e83f554 100644 --- a/src/util.h +++ b/src/util.h @@ -531,6 +531,20 @@ inline uint160 Hash160(const std::vector& vch) return hash2; } +/** + * Timing-attack-resistant comparison. + * Takes time proportional to length + * of first argument. + */ +template +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 -- 1.7.1