Block-Keys are created randomly

This commit is contained in:
Sebastian Messmer 2014-12-06 11:22:34 +01:00
parent 11b74dd035
commit 2d3f329b6a
7 changed files with 152 additions and 8 deletions

View File

@ -1,3 +1,3 @@
add_library(blobstore_ondisk Data.cpp OnDiskBlob.cpp OnDiskBlobStore.cpp FileAlreadyExistsException.cpp FileDoesntExistException.cpp)
add_library(blobstore_ondisk Data.cpp OnDiskBlob.cpp OnDiskBlobStore.cpp RandomKeyGenerator.cpp FileAlreadyExistsException.cpp FileDoesntExistException.cpp)
target_link_libraries(blobstore_ondisk boost_filesystem boost_system)
target_link_libraries(blobstore_ondisk boost_filesystem boost_system cryptopp)

View File

@ -1,23 +1,45 @@
#include "OnDiskBlobStore.h"
#include "OnDiskBlob.h"
#include "RandomKeyGenerator.h"
using std::unique_ptr;
using std::string;
using std::mutex;
using std::lock_guard;
namespace bf = boost::filesystem;
namespace blobstore {
namespace ondisk {
OnDiskBlobStore::OnDiskBlobStore(const boost::filesystem::path &rootdir)
: _rootdir(rootdir) {}
: _rootdir(rootdir), _generate_key_mutex() {}
BlobStore::BlobWithKey OnDiskBlobStore::create(const std::string &key, size_t size) {
BlobStore::BlobWithKey OnDiskBlobStore::create(size_t size) {
std::string key = _generateKey();
auto file_path = _rootdir / key;
auto blob = OnDiskBlob::CreateOnDisk(file_path, size);
return BlobStore::BlobWithKey(key, std::move(blob));
}
unique_ptr<Blob> OnDiskBlobStore::load(const std::string &key) {
string OnDiskBlobStore::_generateKey() {
lock_guard<mutex> lock(_generate_key_mutex);
string key;
do {
key = _generateRandomKey();
} while (bf::exists(_rootdir / key));
return key;
}
string OnDiskBlobStore::_generateRandomKey() {
return RandomKeyGenerator::singleton().create();
}
unique_ptr<Blob> OnDiskBlobStore::load(const string &key) {
auto file_path = _rootdir / key;
return OnDiskBlob::LoadFromDisk(file_path);
}

View File

@ -4,10 +4,12 @@
#include "blobstore/interface/BlobStore.h"
#include <boost/filesystem/path.hpp>
#include <boost/filesystem.hpp>
#include "fspp/utils/macros.h"
#include <mutex>
namespace blobstore {
namespace ondisk {
class OnDiskBlob;
@ -16,12 +18,16 @@ class OnDiskBlobStore: public BlobStore {
public:
OnDiskBlobStore(const boost::filesystem::path &rootdir);
BlobWithKey create(const std::string &key, size_t size) override;
BlobWithKey create(size_t size) override;
std::unique_ptr<Blob> load(const std::string &key) override;
private:
std::string _generateKey();
std::string _generateRandomKey();
const boost::filesystem::path _rootdir;
std::mutex _generate_key_mutex;
DISALLOW_COPY_AND_ASSIGN(OnDiskBlobStore);
};

View File

@ -0,0 +1,55 @@
#include <blobstore/implementations/ondisk/RandomKeyGenerator.h>
using std::string;
#include <crypto++/hex.h>
#include <crypto++/osrng.h>
using CryptoPP::AutoSeededRandomPool;
using CryptoPP::ArraySource;
using CryptoPP::StringSink;
using CryptoPP::HexEncoder;
using std::make_unique;
namespace blobstore {
namespace ondisk {
constexpr unsigned int RandomKeyGenerator::KEYLENGTH_ENTROPY;
constexpr unsigned int RandomKeyGenerator::KEYLENGTH;
namespace {
string encodeKeyToHex(const byte *data);
}
RandomKeyGenerator::RandomKeyGenerator()
: _randomPool(make_unique<AutoSeededRandomPool>()) {
}
RandomKeyGenerator::~RandomKeyGenerator() {
}
RandomKeyGenerator &RandomKeyGenerator::singleton() {
static RandomKeyGenerator singleton;
return singleton;
}
string RandomKeyGenerator::create() {
byte key[KEYLENGTH_ENTROPY];
_randomPool->GenerateBlock(key, KEYLENGTH_ENTROPY);
return encodeKeyToHex(key);
}
namespace {
string encodeKeyToHex(const byte *data) {
string result;
ArraySource(data, RandomKeyGenerator::KEYLENGTH_ENTROPY, true,
new HexEncoder(new StringSink(result))
);
assert(result.size() == RandomKeyGenerator::KEYLENGTH);
return result;
}
}
} /* namespace ondisk */
} /* namespace blobstore */

View File

@ -0,0 +1,41 @@
#pragma once
#ifndef BLOBSTORE_IMPLEMENTATIONS_ONDISK_RANDOMKEYGENERATOR_H_
#define BLOBSTORE_IMPLEMENTATIONS_ONDISK_RANDOMKEYGENERATOR_H_
#include "Data.h"
#include "fspp/utils/macros.h"
#include <memory>
namespace CryptoPP {
class AutoSeededRandomPool;
}
namespace blobstore {
namespace ondisk {
// Creates random keys for use as block access handles.
// A key here is NOT a key for encryption, but a key as used in key->value mappings ("access handle for a block").
class RandomKeyGenerator {
public:
virtual ~RandomKeyGenerator();
static constexpr unsigned int KEYLENGTH_ENTROPY = 16; // random bytes in the key
static constexpr unsigned int KEYLENGTH = KEYLENGTH_ENTROPY * 2;
static RandomKeyGenerator &singleton();
std::string create();
private:
RandomKeyGenerator();
std::unique_ptr<CryptoPP::AutoSeededRandomPool> _randomPool;
DISALLOW_COPY_AND_ASSIGN(RandomKeyGenerator);
};
} /* namespace ondisk */
} /* namespace blobstore */
#endif

View File

@ -22,7 +22,7 @@ public:
std::unique_ptr<Blob> blob;
};
virtual BlobWithKey create(const std::string &key, size_t size) = 0;
virtual BlobWithKey create(size_t size) = 0;
virtual std::unique_ptr<Blob> load(const std::string &key) = 0;
//TODO Needed for performance? Or is deleting loaded blobs enough?
//virtual void remove(const std::string &key) = 0;

View File

@ -0,0 +1,20 @@
#include "gtest/gtest.h"
#include "blobstore/implementations/ondisk/RandomKeyGenerator.h"
using ::testing::Test;
using std::string;
using namespace blobstore::ondisk;
class RandomKeyGeneratorTest: public Test {};
TEST_F(RandomKeyGeneratorTest, RunsWithoutCrashes) {
string result = RandomKeyGenerator::singleton().create();
}
TEST_F(RandomKeyGeneratorTest, KeySizeIsAsSpecified) {
string result = RandomKeyGenerator::singleton().create();
EXPECT_EQ(RandomKeyGenerator::KEYLENGTH, result.size());
}