diff options
author | Aleksi Lindeman <0xdec05eba@gmail.com> | 2018-03-05 22:45:56 +0100 |
---|---|---|
committer | Aleksi Lindeman <0xdec05eba@gmail.com> | 2018-03-05 22:48:26 +0100 |
commit | 2ffb47d0043e57707474e5ae811f97c2e5e93f25 (patch) | |
tree | fd60b300cdf736de5adc68b395105dcfc6a43f09 /include | |
parent | 66661e47dc826f50b690e080057f47a0ea27016c (diff) |
Implement 'create' operation, add seeding
Seeding is currently only done on the key you specify, in the future
the user should request data that it can seed.
Diffstat (limited to 'include')
-rw-r--r-- | include/Database.hpp | 121 | ||||
-rw-r--r-- | include/DatabaseStorage.hpp | 18 | ||||
-rw-r--r-- | include/DhtKey.hpp | 19 | ||||
-rw-r--r-- | include/Encryption.hpp | 56 | ||||
-rw-r--r-- | include/Group.hpp | 8 | ||||
-rw-r--r-- | include/Hash.hpp | 46 | ||||
-rw-r--r-- | include/Key.hpp | 29 | ||||
-rw-r--r-- | include/StagedObject.hpp | 38 | ||||
-rw-r--r-- | include/bin2hex.hpp | 23 |
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; + } +} |