Generalized Key to FixedSizeData
This commit is contained in:
parent
86f8ca6dc4
commit
990ca6ca26
14
implementations/encrypted/EncryptionKey.cpp
Normal file
14
implementations/encrypted/EncryptionKey.cpp
Normal file
@ -0,0 +1,14 @@
|
||||
#include "EncryptionKey.h"
|
||||
|
||||
namespace blockstore {
|
||||
namespace encrypted {
|
||||
|
||||
EncryptionKey::EncryptionKey() {
|
||||
|
||||
}
|
||||
|
||||
EncryptionKey::~EncryptionKey() {
|
||||
}
|
||||
|
||||
}
|
||||
}
|
19
implementations/encrypted/EncryptionKey.h
Normal file
19
implementations/encrypted/EncryptionKey.h
Normal file
@ -0,0 +1,19 @@
|
||||
#pragma once
|
||||
#ifndef MESSMER_BLOCKSTORE_IMPLEMENTATIONS_ENCRYPTED_ENCRYPTIONKEY_H_
|
||||
#define MESSMER_BLOCKSTORE_IMPLEMENTATIONS_ENCRYPTED_ENCRYPTIONKEY_H_
|
||||
|
||||
namespace blockstore {
|
||||
namespace encrypted {
|
||||
|
||||
class EncryptionKey {
|
||||
public:
|
||||
EncryptionKey();
|
||||
static EncryptionKey
|
||||
private:
|
||||
byte key[32];
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
@ -14,7 +14,7 @@ unique_ptr<Block> BlockStoreWithRandomKeys::create(size_t size) {
|
||||
}
|
||||
|
||||
unique_ptr<Block> BlockStoreWithRandomKeys::tryCreate(size_t size) {
|
||||
Key key = Key::CreateRandomKey();
|
||||
Key key = Key::CreateRandom();
|
||||
return create(key, size);
|
||||
}
|
||||
|
||||
|
@ -30,7 +30,7 @@ public:
|
||||
|
||||
class BlockMock: public Block {
|
||||
public:
|
||||
BlockMock(): Block(Key::CreateRandomKey()) {}
|
||||
BlockMock(): Block(Key::CreateRandom()) {}
|
||||
MOCK_CONST_METHOD0(data, const void*());
|
||||
MOCK_METHOD3(write, void(const void*, uint64_t, uint64_t));
|
||||
MOCK_METHOD0(flush, void());
|
||||
@ -62,7 +62,7 @@ TEST_F(BlockStoreWithRandomKeysTest, SizeIsPassedThrough1024) {
|
||||
|
||||
TEST_F(BlockStoreWithRandomKeysTest, KeyHasCorrectSize) {
|
||||
EXPECT_CALL(blockStoreMock, do_create(_, _)).WillOnce(Invoke([](const Key &key, size_t) {
|
||||
EXPECT_EQ(Key::KEYLENGTH_STRING, key.ToString().size());
|
||||
EXPECT_EQ(Key::STRING_LENGTH, key.ToString().size());
|
||||
return new BlockMock;
|
||||
}));
|
||||
|
||||
|
@ -20,7 +20,7 @@ public:
|
||||
const DataBlockFixture KEY3_AS_BINARY;
|
||||
const DataBlockFixture KEY4_AS_BINARY;
|
||||
|
||||
KeyTest() : KEY3_AS_BINARY(Key::KEYLENGTH_BINARY, 1), KEY4_AS_BINARY(Key::KEYLENGTH_BINARY, 2) {}
|
||||
KeyTest() : KEY3_AS_BINARY(Key::BINARY_LENGTH, 1), KEY4_AS_BINARY(Key::BINARY_LENGTH, 2) {}
|
||||
|
||||
void EXPECT_DATA_EQ(const DataBlockFixture &expected, const Data &actual) {
|
||||
EXPECT_EQ(expected.size(), actual.size());
|
||||
@ -29,12 +29,12 @@ public:
|
||||
};
|
||||
|
||||
TEST_F(KeyTest, CanGenerateRandomKeysWithoutCrashing) {
|
||||
Key result = Key::CreateRandomKey();
|
||||
Key result = Key::CreateRandom();
|
||||
}
|
||||
|
||||
TEST_F(KeyTest, CreatedRandomKeysHaveCorrectLength) {
|
||||
Key key = Key::CreateRandomKey();
|
||||
EXPECT_EQ(Key::KEYLENGTH_STRING, key.ToString().size());
|
||||
Key key = Key::CreateRandom();
|
||||
EXPECT_EQ(Key::STRING_LENGTH, key.ToString().size());
|
||||
}
|
||||
|
||||
TEST_F(KeyTest, EqualsTrue) {
|
||||
@ -88,20 +88,20 @@ public:
|
||||
static const DataBlockFixture VALUE1;
|
||||
static const DataBlockFixture VALUE2;
|
||||
};
|
||||
const DataBlockFixture KeyTestWithBinaryKeyParam::VALUE1(Key::KEYLENGTH_BINARY, 3);
|
||||
const DataBlockFixture KeyTestWithBinaryKeyParam::VALUE2(Key::KEYLENGTH_BINARY, 4);
|
||||
const DataBlockFixture KeyTestWithBinaryKeyParam::VALUE1(Key::BINARY_LENGTH, 3);
|
||||
const DataBlockFixture KeyTestWithBinaryKeyParam::VALUE2(Key::BINARY_LENGTH, 4);
|
||||
INSTANTIATE_TEST_CASE_P(KeyTestWithBinaryKeyParam, KeyTestWithBinaryKeyParam, Values(&KeyTestWithBinaryKeyParam::VALUE1, &KeyTestWithBinaryKeyParam::VALUE2));
|
||||
|
||||
TEST_P(KeyTestWithBinaryKeyParam, FromAndToBinary) {
|
||||
Key key = Key::FromBinary((uint8_t*)GetParam()->data());
|
||||
Data keydata(Key::KEYLENGTH_BINARY);
|
||||
Data keydata(Key::BINARY_LENGTH);
|
||||
key.ToBinary(keydata.data());
|
||||
EXPECT_DATA_EQ(*GetParam(), keydata);
|
||||
}
|
||||
|
||||
TEST_P(KeyTestWithBinaryKeyParam, ToAndFromBinary) {
|
||||
Key key = Key::FromBinary((uint8_t*)GetParam()->data());
|
||||
Data stored(Key::KEYLENGTH_BINARY);
|
||||
Data stored(Key::BINARY_LENGTH);
|
||||
key.ToBinary(stored.data());
|
||||
Key loaded = Key::FromBinary(stored.data());
|
||||
EXPECT_EQ(key, loaded);
|
||||
@ -138,5 +138,5 @@ TEST_F(KeyTest, AssignmentDoesntChangeSource) {
|
||||
// This tests that a Key object is very lightweight
|
||||
// (we will often pass keys around)
|
||||
TEST_F(KeyTest, KeyIsLightweightObject) {
|
||||
EXPECT_EQ(Key::KEYLENGTH_BINARY, sizeof(Key));
|
||||
EXPECT_EQ(Key::BINARY_LENGTH, sizeof(Key));
|
||||
}
|
||||
|
121
utils/FixedSizeData.h
Normal file
121
utils/FixedSizeData.h
Normal file
@ -0,0 +1,121 @@
|
||||
#pragma once
|
||||
#ifndef BLOCKSTORE_UTILS_data_H_
|
||||
#define BLOCKSTORE_UTILS_data_H_
|
||||
|
||||
#include <cryptopp/cryptopp/hex.h>
|
||||
#include <cryptopp/cryptopp/osrng.h>
|
||||
#include <string>
|
||||
#include <cstring>
|
||||
|
||||
namespace blockstore {
|
||||
|
||||
template<int SIZE>
|
||||
class FixedSizeData {
|
||||
public:
|
||||
//Non-virtual destructor because we want objects to be small
|
||||
~FixedSizeData() {}
|
||||
|
||||
static constexpr unsigned int BINARY_LENGTH = SIZE;
|
||||
static constexpr unsigned int STRING_LENGTH = 2 * BINARY_LENGTH; // Hex encoding
|
||||
|
||||
static FixedSizeData<SIZE> CreateRandom();
|
||||
|
||||
static FixedSizeData<SIZE> FromString(const std::string &data);
|
||||
std::string ToString() const;
|
||||
|
||||
static FixedSizeData<SIZE> FromBinary(const void *source);
|
||||
void ToBinary(void *target) const;
|
||||
|
||||
const unsigned char *data() const;
|
||||
|
||||
private:
|
||||
FixedSizeData() {}
|
||||
|
||||
static CryptoPP::AutoSeededRandomPool &RandomPool();
|
||||
|
||||
unsigned char _data[BINARY_LENGTH];
|
||||
};
|
||||
|
||||
template<int SIZE> bool operator==(const FixedSizeData<SIZE> &lhs, const FixedSizeData<SIZE> &rhs);
|
||||
template<int SIZE> bool operator!=(const FixedSizeData<SIZE> &lhs, const FixedSizeData<SIZE> &rhs);
|
||||
|
||||
//operator< is defined, so that FixedSizeData objects can be used in std::map and std::set
|
||||
template<int SIZE> bool operator<(const FixedSizeData<SIZE> &lhs, const FixedSizeData<SIZE> &rhs);
|
||||
|
||||
// ----- Implementation -----
|
||||
|
||||
template<int SIZE> constexpr unsigned int FixedSizeData<SIZE>::BINARY_LENGTH;
|
||||
template<int SIZE> constexpr unsigned int FixedSizeData<SIZE>::STRING_LENGTH;
|
||||
|
||||
template<int SIZE>
|
||||
CryptoPP::AutoSeededRandomPool &FixedSizeData<SIZE>::RandomPool() {
|
||||
static CryptoPP::AutoSeededRandomPool singleton;
|
||||
return singleton;
|
||||
}
|
||||
|
||||
template<int SIZE>
|
||||
FixedSizeData<SIZE> FixedSizeData<SIZE>::CreateRandom() {
|
||||
FixedSizeData<SIZE> result;
|
||||
RandomPool().GenerateBlock(result._data, BINARY_LENGTH);
|
||||
return result;
|
||||
}
|
||||
|
||||
template<int SIZE>
|
||||
FixedSizeData<SIZE> FixedSizeData<SIZE>::FromString(const std::string &data) {
|
||||
assert(data.size() == STRING_LENGTH);
|
||||
FixedSizeData<SIZE> result;
|
||||
CryptoPP::StringSource(data, true,
|
||||
new CryptoPP::HexDecoder(
|
||||
new CryptoPP::ArraySink(result._data, BINARY_LENGTH)
|
||||
)
|
||||
);
|
||||
return result;
|
||||
}
|
||||
|
||||
template<int SIZE>
|
||||
std::string FixedSizeData<SIZE>::ToString() const {
|
||||
std::string result;
|
||||
CryptoPP::ArraySource(_data, BINARY_LENGTH, true,
|
||||
new CryptoPP::HexEncoder(
|
||||
new CryptoPP::StringSink(result)
|
||||
)
|
||||
);
|
||||
assert(result.size() == STRING_LENGTH);
|
||||
return result;
|
||||
}
|
||||
|
||||
template<int SIZE>
|
||||
const unsigned char *FixedSizeData<SIZE>::data() const {
|
||||
return _data;
|
||||
}
|
||||
|
||||
template<int SIZE>
|
||||
void FixedSizeData<SIZE>::ToBinary(void *target) const {
|
||||
std::memcpy(target, _data, BINARY_LENGTH);
|
||||
}
|
||||
|
||||
template<int SIZE>
|
||||
FixedSizeData<SIZE> FixedSizeData<SIZE>::FromBinary(const void *source) {
|
||||
FixedSizeData<SIZE> result;
|
||||
std::memcpy(result._data, source, BINARY_LENGTH);
|
||||
return result;
|
||||
}
|
||||
|
||||
template<int SIZE>
|
||||
bool operator==(const FixedSizeData<SIZE> &lhs, const FixedSizeData<SIZE> &rhs) {
|
||||
return 0 == std::memcmp(lhs.data(), rhs.data(), FixedSizeData<SIZE>::BINARY_LENGTH);
|
||||
}
|
||||
|
||||
template<int SIZE>
|
||||
bool operator!=(const FixedSizeData<SIZE> &lhs, const FixedSizeData<SIZE> &rhs) {
|
||||
return !operator==(lhs, rhs);
|
||||
}
|
||||
|
||||
template<int SIZE>
|
||||
bool operator<(const FixedSizeData<SIZE> &lhs, const FixedSizeData<SIZE> &rhs) {
|
||||
return 0 > std::memcmp(lhs.data(), rhs.data(), FixedSizeData<SIZE>::BINARY_LENGTH);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif
|
@ -1,83 +1 @@
|
||||
#include <cryptopp/cryptopp/hex.h>
|
||||
#include <cryptopp/cryptopp/osrng.h>
|
||||
#include "Key.h"
|
||||
|
||||
#include <cstring>
|
||||
|
||||
using CryptoPP::ArraySource;
|
||||
using CryptoPP::ArraySink;
|
||||
using CryptoPP::StringSink;
|
||||
using CryptoPP::StringSource;
|
||||
using CryptoPP::HexEncoder;
|
||||
using CryptoPP::HexDecoder;
|
||||
using CryptoPP::AutoSeededRandomPool;
|
||||
|
||||
using std::string;
|
||||
|
||||
namespace blockstore {
|
||||
|
||||
constexpr unsigned int Key::KEYLENGTH_BINARY;
|
||||
constexpr unsigned int Key::KEYLENGTH_STRING;
|
||||
|
||||
Key::Key() {
|
||||
}
|
||||
|
||||
Key::~Key() {
|
||||
}
|
||||
|
||||
AutoSeededRandomPool &RandomPool() {
|
||||
static AutoSeededRandomPool singleton;
|
||||
return singleton;
|
||||
}
|
||||
|
||||
Key Key::CreateRandomKey() {
|
||||
Key result;
|
||||
RandomPool().GenerateBlock(result._key, KEYLENGTH_BINARY);
|
||||
return result;
|
||||
}
|
||||
|
||||
Key Key::FromString(const std::string &key) {
|
||||
assert(key.size() == KEYLENGTH_STRING);
|
||||
Key result;
|
||||
StringSource(key, true,
|
||||
new HexDecoder(new ArraySink(result._key, KEYLENGTH_BINARY))
|
||||
);
|
||||
return result;
|
||||
}
|
||||
|
||||
string Key::ToString() const {
|
||||
string result;
|
||||
ArraySource(_key, KEYLENGTH_BINARY, true,
|
||||
new HexEncoder(new StringSink(result))
|
||||
);
|
||||
assert(result.size() == KEYLENGTH_STRING);
|
||||
return result;
|
||||
}
|
||||
|
||||
const unsigned char *Key::data() const {
|
||||
return _key;
|
||||
}
|
||||
|
||||
bool operator==(const Key &lhs, const Key &rhs) {
|
||||
return 0 == std::memcmp(lhs.data(), rhs.data(), Key::KEYLENGTH_BINARY);
|
||||
}
|
||||
|
||||
bool operator!=(const Key &lhs, const Key &rhs) {
|
||||
return !operator==(lhs, rhs);
|
||||
}
|
||||
|
||||
bool operator<(const Key &lhs, const Key &rhs) {
|
||||
return 0 > std::memcmp(lhs.data(), rhs.data(), Key::KEYLENGTH_BINARY);
|
||||
}
|
||||
|
||||
void Key::ToBinary(void *target) const {
|
||||
std::memcpy(target, _key, KEYLENGTH_BINARY);
|
||||
}
|
||||
|
||||
Key Key::FromBinary(const void *source) {
|
||||
Key result;
|
||||
std::memcpy(result._key, source, KEYLENGTH_BINARY);
|
||||
return result;
|
||||
}
|
||||
|
||||
}
|
||||
|
31
utils/Key.h
31
utils/Key.h
@ -3,39 +3,12 @@
|
||||
#define BLOCKSTORE_UTILS_KEY_H_
|
||||
|
||||
#include <string>
|
||||
#include "FixedSizeData.h"
|
||||
|
||||
namespace blockstore {
|
||||
|
||||
// A key here is NOT a key for encryption, but a key as used in key->value mappings ("access handle for a block").
|
||||
class Key {
|
||||
public:
|
||||
//Non-virtual destructor because we want Key objects to be small
|
||||
~Key();
|
||||
|
||||
static constexpr unsigned int KEYLENGTH_BINARY = 16;
|
||||
static constexpr unsigned int KEYLENGTH_STRING = 2 * KEYLENGTH_BINARY; // Hex encoding
|
||||
|
||||
static Key CreateRandomKey();
|
||||
|
||||
static Key FromString(const std::string &key);
|
||||
std::string ToString() const;
|
||||
|
||||
static Key FromBinary(const void *source);
|
||||
void ToBinary(void *target) const;
|
||||
|
||||
const unsigned char *data() const;
|
||||
|
||||
private:
|
||||
Key();
|
||||
|
||||
unsigned char _key[KEYLENGTH_BINARY];
|
||||
};
|
||||
|
||||
bool operator==(const Key &lhs, const Key &rhs);
|
||||
bool operator!=(const Key &lhs, const Key &rhs);
|
||||
|
||||
//operator< is defined, so that Key objects can be used in std::map and std::set
|
||||
bool operator<(const Key &lhs, const Key &rhs);
|
||||
using Key = FixedSizeData<16>;
|
||||
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user