diff options
author | Wladimir J. van der Laan <laanwj@gmail.com> | 2015-10-06 17:32:18 +0200 |
---|---|---|
committer | Wladimir J. van der Laan <laanwj@gmail.com> | 2015-10-06 17:50:46 +0200 |
commit | 4fac576c619f450da8ca09ac8790063b3dea4364 (patch) | |
tree | 36184ec8419bc1ae12a0285c58406a745e7a6d71 /src/test | |
parent | b7d78fd0bd244b324ded4131c1dd0ec81a87d15d (diff) | |
parent | 42cb388167ef78f47a3a440eb651b6938c10f508 (diff) |
Merge pull request #6650
42cb388 Add chainstate obfuscation to avoid spurious antivirus detection (James O'Beirne)
Diffstat (limited to 'src/test')
-rw-r--r-- | src/test/leveldbwrapper_tests.cpp | 128 | ||||
-rw-r--r-- | src/test/streams_tests.cpp | 67 |
2 files changed, 195 insertions, 0 deletions
diff --git a/src/test/leveldbwrapper_tests.cpp b/src/test/leveldbwrapper_tests.cpp new file mode 100644 index 0000000000..db04f3ea48 --- /dev/null +++ b/src/test/leveldbwrapper_tests.cpp @@ -0,0 +1,128 @@ +// Copyright (c) 2012-2013 The Bitcoin Core developers +// Distributed under the MIT software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. + +#include "leveldbwrapper.h" +#include "uint256.h" +#include "random.h" +#include "test/test_bitcoin.h" + +#include <boost/assign/std/vector.hpp> // for 'operator+=()' +#include <boost/assert.hpp> +#include <boost/test/unit_test.hpp> + +using namespace std; +using namespace boost::assign; // bring 'operator+=()' into scope +using namespace boost::filesystem; + +// Test if a string consists entirely of null characters +bool is_null_key(const vector<unsigned char>& key) { + bool isnull = true; + + for (unsigned int i = 0; i < key.size(); i++) + isnull &= (key[i] == '\x00'); + + return isnull; +} + +BOOST_FIXTURE_TEST_SUITE(leveldbwrapper_tests, BasicTestingSetup) + +BOOST_AUTO_TEST_CASE(leveldbwrapper) +{ + // Perform tests both obfuscated and non-obfuscated. + for (int i = 0; i < 2; i++) { + bool obfuscate = (bool)i; + path ph = temp_directory_path() / unique_path(); + CLevelDBWrapper dbw(ph, (1 << 20), true, false, obfuscate); + char key = 'k'; + uint256 in = GetRandHash(); + uint256 res; + + // Ensure that we're doing real obfuscation when obfuscate=true + BOOST_CHECK(obfuscate != is_null_key(dbw.GetObfuscateKey())); + + BOOST_CHECK(dbw.Write(key, in)); + BOOST_CHECK(dbw.Read(key, res)); + BOOST_CHECK_EQUAL(res.ToString(), in.ToString()); + } +} + +// Test that we do not obfuscation if there is existing data. +BOOST_AUTO_TEST_CASE(existing_data_no_obfuscate) +{ + // We're going to share this path between two wrappers + path ph = temp_directory_path() / unique_path(); + create_directories(ph); + + // Set up a non-obfuscated wrapper to write some initial data. + CLevelDBWrapper* dbw = new CLevelDBWrapper(ph, (1 << 10), false, false, false); + char key = 'k'; + uint256 in = GetRandHash(); + uint256 res; + + BOOST_CHECK(dbw->Write(key, in)); + BOOST_CHECK(dbw->Read(key, res)); + BOOST_CHECK_EQUAL(res.ToString(), in.ToString()); + + // Call the destructor to free leveldb LOCK + delete dbw; + + // Now, set up another wrapper that wants to obfuscate the same directory + CLevelDBWrapper odbw(ph, (1 << 10), false, false, true); + + // Check that the key/val we wrote with unobfuscated wrapper exists and + // is readable. + uint256 res2; + BOOST_CHECK(odbw.Read(key, res2)); + BOOST_CHECK_EQUAL(res2.ToString(), in.ToString()); + + BOOST_CHECK(!odbw.IsEmpty()); // There should be existing data + BOOST_CHECK(is_null_key(odbw.GetObfuscateKey())); // The key should be an empty string + + uint256 in2 = GetRandHash(); + uint256 res3; + + // Check that we can write successfully + BOOST_CHECK(odbw.Write(key, in2)); + BOOST_CHECK(odbw.Read(key, res3)); + BOOST_CHECK_EQUAL(res3.ToString(), in2.ToString()); +} + +// Ensure that we start obfuscating during a reindex. +BOOST_AUTO_TEST_CASE(existing_data_reindex) +{ + // We're going to share this path between two wrappers + path ph = temp_directory_path() / unique_path(); + create_directories(ph); + + // Set up a non-obfuscated wrapper to write some initial data. + CLevelDBWrapper* dbw = new CLevelDBWrapper(ph, (1 << 10), false, false, false); + char key = 'k'; + uint256 in = GetRandHash(); + uint256 res; + + BOOST_CHECK(dbw->Write(key, in)); + BOOST_CHECK(dbw->Read(key, res)); + BOOST_CHECK_EQUAL(res.ToString(), in.ToString()); + + // Call the destructor to free leveldb LOCK + delete dbw; + + // Simulate a -reindex by wiping the existing data store + CLevelDBWrapper odbw(ph, (1 << 10), false, true, true); + + // Check that the key/val we wrote with unobfuscated wrapper doesn't exist + uint256 res2; + BOOST_CHECK(!odbw.Read(key, res2)); + BOOST_CHECK(!is_null_key(odbw.GetObfuscateKey())); + + uint256 in2 = GetRandHash(); + uint256 res3; + + // Check that we can write successfully + BOOST_CHECK(odbw.Write(key, in2)); + BOOST_CHECK(odbw.Read(key, res3)); + BOOST_CHECK_EQUAL(res3.ToString(), in2.ToString()); +} + +BOOST_AUTO_TEST_SUITE_END() diff --git a/src/test/streams_tests.cpp b/src/test/streams_tests.cpp new file mode 100644 index 0000000000..0ed8f363d7 --- /dev/null +++ b/src/test/streams_tests.cpp @@ -0,0 +1,67 @@ +// Copyright (c) 2012-2013 The Bitcoin Core developers +// Distributed under the MIT software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. + +#include "streams.h" +#include "support/allocators/zeroafterfree.h" +#include "test/test_bitcoin.h" + +#include <boost/assign/std/vector.hpp> // for 'operator+=()' +#include <boost/assert.hpp> +#include <boost/test/unit_test.hpp> + +using namespace std; +using namespace boost::assign; // bring 'operator+=()' into scope + +BOOST_FIXTURE_TEST_SUITE(streams_tests, BasicTestingSetup) + +BOOST_AUTO_TEST_CASE(streams_serializedata_xor) +{ + std::vector<char> in; + std::vector<char> expected_xor; + std::vector<unsigned char> key; + CDataStream ds(in, 0, 0); + + // Degenerate case + + key += '\x00','\x00'; + ds.Xor(key); + BOOST_CHECK_EQUAL( + std::string(expected_xor.begin(), expected_xor.end()), + std::string(ds.begin(), ds.end())); + + in += '\x0f','\xf0'; + expected_xor += '\xf0','\x0f'; + + // Single character key + + ds.clear(); + ds.insert(ds.begin(), in.begin(), in.end()); + key.clear(); + + key += '\xff'; + ds.Xor(key); + BOOST_CHECK_EQUAL( + std::string(expected_xor.begin(), expected_xor.end()), + std::string(ds.begin(), ds.end())); + + // Multi character key + + in.clear(); + expected_xor.clear(); + in += '\xf0','\x0f'; + expected_xor += '\x0f','\x00'; + + ds.clear(); + ds.insert(ds.begin(), in.begin(), in.end()); + + key.clear(); + key += '\xff','\x0f'; + + ds.Xor(key); + BOOST_CHECK_EQUAL( + std::string(expected_xor.begin(), expected_xor.end()), + std::string(ds.begin(), ds.end())); +} + +BOOST_AUTO_TEST_SUITE_END() |