aboutsummaryrefslogtreecommitdiff
path: root/include
diff options
context:
space:
mode:
Diffstat (limited to 'include')
-rw-r--r--include/Database.hpp121
-rw-r--r--include/DatabaseStorage.hpp18
-rw-r--r--include/DhtKey.hpp19
-rw-r--r--include/Encryption.hpp56
-rw-r--r--include/Group.hpp8
-rw-r--r--include/Hash.hpp46
-rw-r--r--include/Key.hpp29
-rw-r--r--include/StagedObject.hpp38
-rw-r--r--include/bin2hex.hpp23
9 files changed, 267 insertions, 91 deletions
diff --git a/include/Database.hpp b/include/Database.hpp
index e8b35bb..d160133 100644
--- a/include/Database.hpp
+++ b/include/Database.hpp
@@ -2,17 +2,110 @@
#include "types.hpp"
#include "Key.hpp"
-#include "StagedObject.hpp"
#include "DataView.hpp"
#include "DatabaseStorage.hpp"
+#include "Hash.hpp"
+#include "utils.hpp"
+#include "StagedObject.hpp"
+#include "Signature.hpp"
#include <opendht/dhtrunner.h>
#include <vector>
#include <ntp/NtpClient.hpp>
#include <boost/filesystem/path.hpp>
+#include <stdexcept>
namespace odhtdb
{
class LocalUser;
+ class Group;
+
+ class CommitCreateException : public std::runtime_error
+ {
+ public:
+ CommitCreateException(const std::string &errMsg) : std::runtime_error(errMsg) {}
+ };
+
+ class CommitAddException : public std::runtime_error
+ {
+ public:
+ CommitAddException(const std::string &errMsg) : std::runtime_error(errMsg) {}
+ };
+
+ class DatabaseCreateException : public std::runtime_error
+ {
+ public:
+ DatabaseCreateException(const std::string &errMsg) : std::runtime_error(errMsg) {}
+ };
+
+ class DatabaseAddException : public std::runtime_error
+ {
+ public:
+ DatabaseAddException(const std::string &errMsg) : std::runtime_error(errMsg) {}
+ };
+
+ struct DatabaseCreateRequest
+ {
+ DISABLE_COPY(DatabaseCreateRequest)
+
+ u64 timestamp; // In microseconds
+ Group *creatorGroup;
+ std::string name;
+
+ DatabaseCreateRequest(u64 _timestamp, Group *_creatorGroup, std::string &&_name) :
+ timestamp(_timestamp),
+ creatorGroup(_creatorGroup),
+ name(std::move(_name))
+ {
+
+ }
+
+ DatabaseCreateRequest(DatabaseCreateRequest &&other)
+ {
+ timestamp = other.timestamp;
+ creatorGroup = other.creatorGroup;
+ name = std::move(other.name);
+
+ other.timestamp = 0;
+ other.creatorGroup = nullptr;
+ }
+ };
+
+ struct DatabaseAddRequest
+ {
+ DISABLE_COPY(DatabaseAddRequest)
+
+ u16 packetStructureVersion;
+ u64 timestamp; // In microseconds
+ Signature::PublicKey creatorPublicKey;
+ DataView data;
+
+ DatabaseAddRequest(u16 _packetStructureVersion, u64 _timestamp, Signature::PublicKey &&_creatorPublicKey, DataView &_data) :
+ packetStructureVersion(_packetStructureVersion),
+ timestamp(_timestamp),
+ creatorPublicKey(std::move(_creatorPublicKey)),
+ data(_data)
+ {
+
+ }
+
+ ~DatabaseAddRequest()
+ {
+ free(data.data);
+ data = DataView();
+ }
+ };
+
+ class DatabaseCreateResponse
+ {
+ public:
+ DatabaseCreateResponse(const std::shared_ptr<char*> &key, const std::shared_ptr<Hash> &hash);
+
+ const std::shared_ptr<char*> getNodeEncryptionKey() const;
+ const std::shared_ptr<Hash> getRequestHash() const;
+ private:
+ std::shared_ptr<char*> key;
+ std::shared_ptr<Hash> hash;
+ };
class Database
{
@@ -20,22 +113,26 @@ namespace odhtdb
Database(const char *bootstrapNodeAddr, u16 port, boost::filesystem::path storageDir);
~Database();
- void seed();
- void create(LocalUser *owner, const Key &key);
- void add(LocalUser *owner, const Key &key, DataView data);
+ void seed(const std::shared_ptr<Hash> hash, const std::shared_ptr<char*> encryptionKey);
+ // Throws DatabaseCreateException on failure.
+ std::unique_ptr<DatabaseCreateResponse> create(const LocalUser *owner, const std::string &name);
+ // Throws DatabaseAddException on failure
+ void add(const LocalUser *owner, const Key &key, DataView data);
void commit();
private:
- void commitStagedCreateObject(const StagedCreateObject &stagedObject);
- void commitStagedAddObject(const StagedAddObject &stagedObject);
+ // Throws CommitCreateException on failure
+ void commitStagedCreateObject(const std::unique_ptr<StagedCreateObject> &stagedObject);
+ // Throws CommitAddException on failure
+ void commitStagedAddObject(const DataView &stagedObject);
ntp::NtpTimestamp getSyncedTimestampUtc() const;
- StagedCreateObject deserializeCreateRequest(const std::shared_ptr<dht::Value> &value);
- StagedAddObject deserializeAddRequest(const std::shared_ptr<dht::Value> &value);
- bool listenCreateData(std::shared_ptr<dht::Value> value);
- bool listenAddData(std::shared_ptr<dht::Value> value);
+ DatabaseCreateRequest deserializeCreateRequest(const std::shared_ptr<dht::Value> &value, const Hash &hash, const std::shared_ptr<char*> encryptionKey);
+ DatabaseAddRequest deserializeAddRequest(const std::shared_ptr<dht::Value> &value, const Hash &hash, const std::shared_ptr<char*> encryptionKey);
+ bool listenCreateData(std::shared_ptr<dht::Value> value, const Hash &hash, const std::shared_ptr<char*> encryptionKey);
+ bool listenAddData(std::shared_ptr<dht::Value> value, const Hash &hash, const std::shared_ptr<char*> encryptionKey);
private:
dht::DhtRunner node;
- std::vector<StagedCreateObject> stagedCreateObjects;
- std::vector<StagedAddObject> stagedAddObjects;
+ std::vector<std::unique_ptr<StagedCreateObject>> stagedCreateObjects;
+ std::vector<std::unique_ptr<DataView>> stagedAddObjects;
DatabaseStorage databaseStorage;
};
}
diff --git a/include/DatabaseStorage.hpp b/include/DatabaseStorage.hpp
index 863c5d9..6f251d1 100644
--- a/include/DatabaseStorage.hpp
+++ b/include/DatabaseStorage.hpp
@@ -1,8 +1,9 @@
#pragma once
-#include "Key.hpp"
+#include "Hash.hpp"
#include "DataView.hpp"
#include "Signature.hpp"
+#include "Encryption.hpp"
#include <vector>
#include <stdexcept>
@@ -28,6 +29,8 @@ namespace odhtdb
u64 timestamp; // In microseconds
std::vector<Group*> groups;
std::vector<DatabaseStorageObject> objects;
+ u8 *createData;
+ usize createDataSize;
};
class DatabaseStorageAlreadyExists : public std::runtime_error
@@ -42,16 +45,19 @@ namespace odhtdb
DatabaseStorageNotFound(const std::string &errMsg) : std::runtime_error(errMsg) {}
};
- using DatabaseStorageMap = KeyMap<DatabaseStorageObjectList*>;
+ using DatabaseStorageMap = MapHashKey<DatabaseStorageObjectList*>;
class DatabaseStorage
{
public:
- // Throws DatabaseStorageAlreadyExists if data with key already exists
- void createStorage(const Key &key, std::vector<Group*> &&groups, u64 timestamp);
+ // Throws DatabaseStorageAlreadyExists if data with hash already exists
+ void createStorage(const Hash &hash, Group *creatorGroup, u64 timestamp, const u8 *data, usize dataSize);
- // Throws DatabaseStorageNotFound if data with key does not exist
- void appendStorage(const Key &key, DataView &data, u64 timestamp, const Signature::PublicKey &creatorPublicKey);
+ // Throws DatabaseStorageNotFound if data with hash does not exist
+ void appendStorage(const Hash &hash, DataView &data, u64 timestamp, const Signature::PublicKey &creatorPublicKey);
+
+ // Returns nullptr if not storage with provided hash exists
+ const DatabaseStorageObjectList* getStorage(const Hash &hash) const;
private:
DatabaseStorageMap storageMap;
};
diff --git a/include/DhtKey.hpp b/include/DhtKey.hpp
new file mode 100644
index 0000000..7c30ee3
--- /dev/null
+++ b/include/DhtKey.hpp
@@ -0,0 +1,19 @@
+#pragma once
+
+#include "Hash.hpp"
+#include <opendht/infohash.h>
+
+namespace odhtdb
+{
+ class DhtKey
+ {
+ public:
+ DhtKey(const Hash &key);
+
+ const dht::InfoHash& getNewDataListenerKey();
+ const dht::InfoHash& getRequestOldDataKey();
+ private:
+ dht::InfoHash infoHash;
+ unsigned char firstByteOriginalValue;
+ };
+}
diff --git a/include/Encryption.hpp b/include/Encryption.hpp
index b70687d..b2afe49 100644
--- a/include/Encryption.hpp
+++ b/include/Encryption.hpp
@@ -1,29 +1,61 @@
#pragma once
/*
- * Encrypts/decrypts data using xchacha20
+ * Encrypts/decrypts data using xchacha20-poly1305 ietf
*/
+#include "DataView.hpp"
+#include "utils.hpp"
#include <string>
+#include <stdexcept>
namespace odhtdb
{
const int NONCE_BYTE_SIZE = 24;
+ const int KEY_BYTE_SIZE = 32;
- struct EncryptedData
+ class EncryptionException : public std::runtime_error
{
- char nonce[NONCE_BYTE_SIZE];
- std::string data;
+ public:
+ EncryptionException(const std::string &errMsg) : std::runtime_error(errMsg) {}
};
- using EncryptionKey = char[32];
-
- // Stores randomly generated encryption key in @output
- void generateEncryptionKey(EncryptionKey *output);
+ class DecryptionException : public std::runtime_error
+ {
+ public:
+ DecryptionException(const std::string &errMsg) : std::runtime_error(errMsg) {}
+ };
- // Returns 0 on success, storing encrypted data in @output
- int encrypt(EncryptedData *output, const EncryptionKey *key, const void *data, size_t dataSize);
+ class Encryption
+ {
+ DISABLE_COPY(Encryption)
+ public:
+ // Throws EncryptionException on failure (or std::bad_alloc on failed memory allocation)
+ Encryption(const DataView &data) : Encryption(data, DataView()) {}
+ Encryption(const DataView &data, const DataView &additionalData);
+ ~Encryption();
+
+ DataView getKey() const;
+ DataView getNonce() const;
+ DataView getCipherText() const;
+ private:
+ unsigned char key[KEY_BYTE_SIZE];
+ unsigned char nonce[NONCE_BYTE_SIZE];
+ unsigned char *cipherText;
+ unsigned long long cipherTextLength;
+ };
- // Returns 0 on success, storing decrypted data in @output
- int decrypt(std::string *output, const EncryptionKey *key, const EncryptedData *encryptedData);
+ class Decryption
+ {
+ DISABLE_COPY(Decryption)
+ public:
+ // Throws DecryptionException on failure
+ Decryption(const DataView &data, const DataView &nonce, const DataView &key);
+ ~Decryption();
+
+ DataView getDecryptedText() const;
+ private:
+ unsigned char *decryptedText;
+ unsigned long long decryptedTextLength;
+ };
}
diff --git a/include/Group.hpp b/include/Group.hpp
index c909728..a8dcf83 100644
--- a/include/Group.hpp
+++ b/include/Group.hpp
@@ -24,12 +24,12 @@ namespace odhtdb
Group(const std::string &name);
~Group();
- void addUser(User *user);
+ void addUser(const User *user);
const std::string& getName() const;
- const std::vector<User*>& getUsers() const;
+ const std::vector<const User*>& getUsers() const;
private:
std::string name;
- std::vector<User*> users;
+ std::vector<const User*> users;
};
-} \ No newline at end of file
+}
diff --git a/include/Hash.hpp b/include/Hash.hpp
new file mode 100644
index 0000000..d7c90b0
--- /dev/null
+++ b/include/Hash.hpp
@@ -0,0 +1,46 @@
+#pragma once
+
+#include "utils.hpp"
+#include <sodium/crypto_generichash_blake2b.h>
+#include <stdexcept>
+#include <unordered_map>
+
+namespace odhtdb
+{
+ const int HASH_BYTE_SIZE = 32;
+
+ class HashException : public std::runtime_error
+ {
+ public:
+ HashException(const std::string &errMsg) : std::runtime_error(errMsg) {}
+ };
+
+ class Hash
+ {
+ public:
+ Hash();
+ // Throws HashException on failure
+ Hash(const void *input, const size_t inputSize);
+
+ void* getData() const { return (void*)data; }
+ size_t getSize() const { return HASH_BYTE_SIZE; }
+
+ size_t operator()() const;
+ bool operator==(const Hash &other) const;
+
+ std::string toString() const;
+ private:
+ char data[HASH_BYTE_SIZE];
+ };
+
+ struct HashHasher
+ {
+ size_t operator()(const Hash &hash) const
+ {
+ return hash();
+ }
+ };
+
+ template <typename ValueType>
+ using MapHashKey = std::unordered_map<Hash, ValueType, HashHasher>;
+}
diff --git a/include/Key.hpp b/include/Key.hpp
index f7a600b..18971d1 100644
--- a/include/Key.hpp
+++ b/include/Key.hpp
@@ -1,7 +1,6 @@
#pragma once
#include <opendht/infohash.h>
-#include <unordered_map>
namespace odhtdb
{
@@ -13,32 +12,4 @@ namespace odhtdb
dht::InfoHash hashedKey;
};
-
- // Source: https://stackoverflow.com/a/11414104 (public license)
- static unsigned int fnvHash(const unsigned char *key, int len)
- {
- unsigned int h = 2166136261;
- for (int i = 0; i < len; i++)
- h = (h * 16777619) ^ key[i];
- return h;
- }
-
- struct KeyHash
- {
- size_t operator()(const Key &key) const
- {
- return fnvHash(key.hashedKey.data(), key.hashedKey.size());
- }
- };
-
- struct KeyCompare
- {
- bool operator()(const Key &lhs, const Key &rhs) const
- {
- return lhs.hashedKey == rhs.hashedKey;
- }
- };
-
- template <typename ValueType>
- using KeyMap = std::unordered_map<Key, ValueType, KeyHash, KeyCompare>;
}
diff --git a/include/StagedObject.hpp b/include/StagedObject.hpp
index fccf4f6..a75664e 100644
--- a/include/StagedObject.hpp
+++ b/include/StagedObject.hpp
@@ -1,40 +1,22 @@
#pragma once
-#include "Key.hpp"
-#include "types.hpp"
+#include "utils.hpp"
+#include "Hash.hpp"
#include "DataView.hpp"
-#include "Signature.hpp"
namespace odhtdb
{
- class Group;
-
struct StagedCreateObject
{
- Key key;
- Group *primaryAdminGroup;
- u64 timestamp; // In microseconds
-
- StagedCreateObject() : key(), primaryAdminGroup(nullptr), timestamp(0) {}
- StagedCreateObject(const Key &_key, Group *_primaryAdminGroup, u64 _timestamp) :
- key(_key), primaryAdminGroup(_primaryAdminGroup), timestamp(_timestamp)
- {
-
- }
- };
-
- struct StagedAddObject
- {
- Key key;
- std::unique_ptr<std::string> data;
- u64 timestamp; // In microseconds
- Signature::PublicKey creatorPublicKey;
-
- StagedAddObject() : key(), data(), timestamp(0), creatorPublicKey(Signature::PublicKey::ZERO) {}
- StagedAddObject(const Key &_key, std::unique_ptr<std::string> &&_data, u64 _timestamp, const Signature::PublicKey &_creatorPublicKey) :
- key(_key), data(std::move(_data)), timestamp(_timestamp), creatorPublicKey(_creatorPublicKey)
+ DISABLE_COPY(StagedCreateObject)
+ DataView encryptedBody;
+ std::shared_ptr<Hash> requestKey;
+
+ StagedCreateObject(DataView &_encryptedBody, const std::shared_ptr<Hash> &_requestKey) :
+ encryptedBody(_encryptedBody),
+ requestKey(_requestKey)
{
-
+
}
};
}
diff --git a/include/bin2hex.hpp b/include/bin2hex.hpp
new file mode 100644
index 0000000..72b57c1
--- /dev/null
+++ b/include/bin2hex.hpp
@@ -0,0 +1,23 @@
+#pragma once
+
+#include <string>
+
+namespace odhtdb
+{
+ static const char HEX_TABLE[] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' };
+
+ static std::string bin2hex(const char *data, size_t dataSize)
+ {
+ std::string result;
+ result.resize(dataSize * 2);
+
+ for(int i = 0; i < dataSize; ++i)
+ {
+ char c = data[i];
+ result[i * 2 + 0] = HEX_TABLE[(c & 0xF0) >> 4];
+ result[i * 2 + 1] = HEX_TABLE[(c & 0x0F)];
+ }
+
+ return result;
+ }
+}