diff options
author | dec05eba <dec05eba@protonmail.com> | 2018-03-13 06:26:06 +0100 |
---|---|---|
committer | dec05eba <dec05eba@protonmail.com> | 2020-08-18 23:25:46 +0200 |
commit | 5a8727e34b938b70623ca865273fd81c7604b461 (patch) | |
tree | a2921e90aa454072dc58fced36b508f67f5d1226 /include/odhtdb | |
parent | 9ffc25c9d99fe86d4789108d1d8615ecb0388cc6 (diff) |
Expose include dir
Diffstat (limited to 'include/odhtdb')
-rw-r--r-- | include/odhtdb/DataView.hpp | 30 | ||||
-rw-r--r-- | include/odhtdb/Database.hpp | 153 | ||||
-rw-r--r-- | include/odhtdb/DatabaseNode.hpp | 31 | ||||
-rw-r--r-- | include/odhtdb/DatabaseStorage.hpp | 95 | ||||
-rw-r--r-- | include/odhtdb/DhtKey.hpp | 19 | ||||
-rw-r--r-- | include/odhtdb/Encryption.hpp | 64 | ||||
-rw-r--r-- | include/odhtdb/Group.hpp | 45 | ||||
-rw-r--r-- | include/odhtdb/Hash.hpp | 58 | ||||
-rw-r--r-- | include/odhtdb/Key.hpp | 15 | ||||
-rw-r--r-- | include/odhtdb/LocalUser.hpp | 29 | ||||
-rw-r--r-- | include/odhtdb/Log.hpp | 12 | ||||
-rw-r--r-- | include/odhtdb/Permission.hpp | 46 | ||||
-rw-r--r-- | include/odhtdb/RemoteUser.hpp | 24 | ||||
-rw-r--r-- | include/odhtdb/Signature.hpp | 126 | ||||
-rw-r--r-- | include/odhtdb/StagedObject.hpp | 22 | ||||
-rw-r--r-- | include/odhtdb/User.hpp | 38 | ||||
-rw-r--r-- | include/odhtdb/bin2hex.hpp | 23 | ||||
-rw-r--r-- | include/odhtdb/types.hpp | 22 | ||||
-rwxr-xr-x | include/odhtdb/utils.hpp | 6 |
19 files changed, 858 insertions, 0 deletions
diff --git a/include/odhtdb/DataView.hpp b/include/odhtdb/DataView.hpp new file mode 100644 index 0000000..0ecf9fb --- /dev/null +++ b/include/odhtdb/DataView.hpp @@ -0,0 +1,30 @@ +#pragma once + +#include "types.hpp" +#include "Hash.hpp" +#include <unordered_map> + +namespace odhtdb +{ + class DataView + { + public: + DataView() : data(nullptr), size(0) {} + DataView(void *_data, usize _size) : data(_data), size(_size) {} + bool operator == (const DataView &other) const; + + void *data; + usize size; + }; + + struct DataViewHasher + { + size_t operator()(const DataView &dataView) const + { + return fnvHash((const unsigned char*)dataView.data, dataView.size); + } + }; + + template <typename ValueType> + using DataViewMap = std::unordered_map<DataView, ValueType, DataViewHasher>; +} diff --git a/include/odhtdb/Database.hpp b/include/odhtdb/Database.hpp new file mode 100644 index 0000000..6bc7bc5 --- /dev/null +++ b/include/odhtdb/Database.hpp @@ -0,0 +1,153 @@ +#pragma once + +#include "types.hpp" +#include "Key.hpp" +#include "DataView.hpp" +#include "DatabaseStorage.hpp" +#include "Hash.hpp" +#include "utils.hpp" +#include "StagedObject.hpp" +#include "Signature.hpp" +#include "Permission.hpp" +#include "DatabaseNode.hpp" +#include <opendht/dhtrunner.h> +#include <vector> +#include <ntp/NtpClient.hpp> +#include <boost/filesystem/path.hpp> +#include <stdexcept> + +namespace odhtdb +{ + class User; + 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) {} + }; + + enum class DatabaseOperation : u8 + { + ADD_DATA, + ADD_USER + }; + + 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) + + u64 timestamp; // In microseconds + const User *creatorUser; + Decryption decryptedData; + + DatabaseAddRequest(u64 _timestamp, const User *_creatorUser, Decryption &&_decryptedData) : + timestamp(_timestamp), + creatorUser(_creatorUser), + decryptedData(std::move(_decryptedData)) + { + + } + + DatabaseAddRequest(DatabaseAddRequest &&other) + { + timestamp = other.timestamp; + creatorUser = other.creatorUser; + decryptedData = std::move(other.decryptedData); + + other.timestamp = 0; + other.creatorUser = nullptr; + } + }; + + class DatabaseCreateResponse + { + public: + DatabaseCreateResponse(LocalUser *nodeAdminUser, const std::shared_ptr<char*> &key, const std::shared_ptr<Hash> &hash); + + const LocalUser* getNodeAdminUser() const; + const std::shared_ptr<char*> getNodeEncryptionKey() const; + const std::shared_ptr<Hash> getRequestHash() const; + private: + LocalUser *nodeAdminUser; + std::shared_ptr<char*> key; + std::shared_ptr<Hash> hash; + }; + + class Database + { + public: + Database(const char *bootstrapNodeAddr, u16 port, boost::filesystem::path storageDir); + ~Database(); + + void seed(const std::shared_ptr<Hash> hash, const std::shared_ptr<char*> encryptionKey); + // Throws DatabaseCreateException on failure. + std::unique_ptr<DatabaseCreateResponse> create(const std::string &ownerName, const std::string &nodeName); + // Throws DatabaseAddException on failure + void addData(const DatabaseNode &nodeInfo, LocalUser *userToPerformActionWith, DataView dataToAdd); + // Throws PermissionDeniedException if user @userToPerformActionWith is not allowed to add user @userToAdd to group @groupToAddUserTo + void addUserToGroup(const DatabaseNode &nodeInfo, LocalUser *userToPerformActionWith, const std::string &userToAddName, const Signature::PublicKey &userToAddPublicKey, Group *groupToAddUserTo); + void commit(); + private: + // Throws CommitCreateException on failure + void commitStagedCreateObject(const std::unique_ptr<StagedObject> &stagedObject); + // Throws CommitAddException on failure + void commitStagedAddObject(const std::unique_ptr<StagedObject> &stagedObject); + ntp::NtpTimestamp getSyncedTimestampUtc() const; + DatabaseCreateRequest deserializeCreateRequest(const std::shared_ptr<dht::Value> &value, const Hash &hash, const std::shared_ptr<char*> encryptionKey); + void deserializeAddRequest(const std::shared_ptr<dht::Value> &value, const Hash &requestDataHash, 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 &requestDataHash, const std::shared_ptr<char*> encryptionKey); + private: + dht::DhtRunner node; + std::vector<std::unique_ptr<StagedObject>> stagedCreateObjects; + std::vector<std::unique_ptr<StagedObject>> stagedAddObjects; + DatabaseStorage databaseStorage; + }; +} diff --git a/include/odhtdb/DatabaseNode.hpp b/include/odhtdb/DatabaseNode.hpp new file mode 100644 index 0000000..3ca4be3 --- /dev/null +++ b/include/odhtdb/DatabaseNode.hpp @@ -0,0 +1,31 @@ +#pragma once + +#include "Hash.hpp" +#include <memory> + +namespace odhtdb +{ + class DatabaseNode + { + public: + DatabaseNode(const std::shared_ptr<char*> &_encryptionKey, const std::shared_ptr<Hash> &_nodeHash) : + encryptionKey(_encryptionKey), + nodeHash(_nodeHash) + { + + } + + const std::shared_ptr<char*> getNodeEncryptionKey() const + { + return encryptionKey; + } + + const std::shared_ptr<Hash> getRequestHash() const + { + return nodeHash; + } + private: + std::shared_ptr<char*> encryptionKey; + std::shared_ptr<Hash> nodeHash; + }; +} diff --git a/include/odhtdb/DatabaseStorage.hpp b/include/odhtdb/DatabaseStorage.hpp new file mode 100644 index 0000000..ad4f70b --- /dev/null +++ b/include/odhtdb/DatabaseStorage.hpp @@ -0,0 +1,95 @@ +#pragma once + +#include "types.hpp" +#include "Hash.hpp" +#include "DataView.hpp" +#include "Signature.hpp" +#include "Encryption.hpp" +#include <vector> +#include <stdexcept> + +namespace odhtdb +{ + class Group; + class User; + + struct DatabaseStorageObject + { + DataView data; + u64 createdTimestamp; // In microseconds + Signature::PublicKey creatorPublicKey; + + DatabaseStorageObject(DataView &_data, u64 _timestamp, const Signature::PublicKey &_creatorPublicKey); + }; + + struct DatabaseStorageObjectList + { + DataView data; + u64 createdTimestamp; // In microseconds + std::vector<Group*> groups; + std::vector<DatabaseStorageObject*> objects; + }; + + struct DatabaseStorageQuarantineObject + { + DataView data; + u64 createdTimestamp; // In microseconds + u64 storedTimestamp; // In microseconds + Signature::PublicKey creatorPublicKey; + + DatabaseStorageQuarantineObject(DataView &_data, u64 _timestamp, const Signature::PublicKey &_creatorPublicKey); + }; + + class DatabaseStorageAlreadyExists : public std::runtime_error + { + public: + DatabaseStorageAlreadyExists(const std::string &errMsg) : std::runtime_error(errMsg) {} + }; + + class DatabaseStorageNotFound : public std::runtime_error + { + public: + DatabaseStorageNotFound(const std::string &errMsg) : std::runtime_error(errMsg) {} + }; + + using DatabaseStorageMap = MapHash<DatabaseStorageObjectList*>; + using DatabaseStorageQuarantineMap = Signature::MapPublicKey<std::vector<DatabaseStorageQuarantineObject*>>; + + class DatabaseStorage + { + public: + // 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 @nodeHash hash has not been created yet. + // Throws DatabaseStorageAlreadyExists if same data has been added before (hash of @data, in @dataHash) + void appendStorage(const Hash &nodeHash, const Hash &dataHash, const User *creatorUser, u64 timestamp, const u8 *data, usize dataSize); + + // Throws DatabaseStorageAlreadyExists if same data has been added before (hash of @data, in @dataHash) + void addToQuarantine(const Hash &dataHash, const Signature::PublicKey &creatorPublicKey, u64 timestamp, const u8 *data, usize dataSize); + + void addUser(User *user, const Hash &hash); + + // Returns nullptr if no storage with provided hash exists + const DatabaseStorageObjectList* getStorage(const Hash &hash) const; + + // Returns nullptr if no node with the user exists + const Hash* getNodeByUserPublicKey(const Signature::PublicKey &userPublicKey) const; + + // Returns nullptr if no user with public key exists + const User* getUserByPublicKey(const Signature::PublicKey &userPublicKey) const; + + // Returns nullptr if a group with id @groupId doesn't exist + Group* getGroupById(uint8_t groupId[16]); + + // Update storage state (remove quarantine objects if they are too old, etc) + void update(); + private: + DatabaseStorageMap storageMap; + DatabaseStorageQuarantineMap quarantineStorageMap; + SetHash storedDataHash; // Prevent duplicate data from being added + Signature::MapPublicKey<Hash*> userPublicKeyNodeMap; + Signature::MapPublicKey<const User*> publicKeyUserMap; + DataViewMap<Group*> groupByIdMap; + }; +} diff --git a/include/odhtdb/DhtKey.hpp b/include/odhtdb/DhtKey.hpp new file mode 100644 index 0000000..7c30ee3 --- /dev/null +++ b/include/odhtdb/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/odhtdb/Encryption.hpp b/include/odhtdb/Encryption.hpp new file mode 100644 index 0000000..4697b35 --- /dev/null +++ b/include/odhtdb/Encryption.hpp @@ -0,0 +1,64 @@ +#pragma once + +/* + * 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; + + class EncryptionException : public std::runtime_error + { + public: + EncryptionException(const std::string &errMsg) : std::runtime_error(errMsg) {} + }; + + class DecryptionException : public std::runtime_error + { + public: + DecryptionException(const std::string &errMsg) : std::runtime_error(errMsg) {} + }; + + class Encryption + { + DISABLE_COPY(Encryption) + public: + // Throws EncryptionException on failure (or std::bad_alloc on failed memory allocation) + Encryption(const DataView &data, const DataView &additionalData = DataView(), const DataView &key = DataView()); + ~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; + }; + + class Decryption + { + DISABLE_COPY(Decryption) + public: + Decryption() : decryptedText(nullptr), decryptedTextLength(0) {} + + // Throws DecryptionException on failure + Decryption(const DataView &data, const DataView &nonce, const DataView &key); + Decryption(Decryption &&other); + Decryption& operator=(Decryption &&other); + ~Decryption(); + + DataView getDecryptedText() const; + private: + unsigned char *decryptedText; + unsigned long long decryptedTextLength; + }; +} diff --git a/include/odhtdb/Group.hpp b/include/odhtdb/Group.hpp new file mode 100644 index 0000000..315961d --- /dev/null +++ b/include/odhtdb/Group.hpp @@ -0,0 +1,45 @@ +#pragma once + +#include "types.hpp" +#include "DataView.hpp" +#include "Permission.hpp" +#include <string> +#include <vector> +#include <stdexcept> + +namespace odhtdb +{ + class User; + + class GroupNameTooLongException : public std::runtime_error + { + public: + GroupNameTooLongException(const std::string &groupName) : + std::runtime_error(std::string("The group name ") + groupName + " is longer than 255 bytes") + { + + } + }; + + + + class Group + { + friend class User; + public: + Group(const std::string &name, uint8_t id[16], const Permission &permission); + ~Group(); + + const std::string& getName() const; + DataView getId() const; + const Permission& getPermission() const; + const std::vector<const User*>& getUsers() const; + private: + void addUser(const User *user); + private: + std::string name; + uint8_t id[16]; + Permission permission; + std::vector<const User*> users; + }; +} diff --git a/include/odhtdb/Hash.hpp b/include/odhtdb/Hash.hpp new file mode 100644 index 0000000..9dce168 --- /dev/null +++ b/include/odhtdb/Hash.hpp @@ -0,0 +1,58 @@ +#pragma once + +#include "utils.hpp" +#include <stdexcept> +#include <unordered_map> +#include <unordered_set> + +namespace odhtdb +{ + const int HASH_BYTE_SIZE = 32; + + // Source: https://stackoverflow.com/a/11414104 (public license) + static size_t fnvHash(const unsigned char *key, int len) + { + size_t h = 2166136261; + for (int i = 0; i < len; i++) + h = (h * 16777619) ^ key[i]; + return h; + } + + 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); + Hash(const Hash &other); + + 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 MapHash = std::unordered_map<Hash, ValueType, HashHasher>; + + using SetHash = std::unordered_set<Hash, HashHasher>; +} diff --git a/include/odhtdb/Key.hpp b/include/odhtdb/Key.hpp new file mode 100644 index 0000000..18971d1 --- /dev/null +++ b/include/odhtdb/Key.hpp @@ -0,0 +1,15 @@ +#pragma once + +#include <opendht/infohash.h> + +namespace odhtdb +{ + class Key + { + public: + Key() {} + Key(const char *key) : hashedKey(dht::InfoHash::get(key)) {} + + dht::InfoHash hashedKey; + }; +} diff --git a/include/odhtdb/LocalUser.hpp b/include/odhtdb/LocalUser.hpp new file mode 100644 index 0000000..d60cb38 --- /dev/null +++ b/include/odhtdb/LocalUser.hpp @@ -0,0 +1,29 @@ +#pragma once + +#include "User.hpp" + +namespace odhtdb +{ + class LocalUser : public User + { + public: + static LocalUser* create(const Signature::KeyPair &keyPair, const std::string &name, Group *group) + { + return new LocalUser(keyPair, name, group); + } + + const Signature::PublicKey& getPublicKey() const override + { + return keyPair.getPublicKey(); + } + + const Signature::PrivateKey& getPrivateKey() const + { + return keyPair.getPrivateKey(); + } + private: + LocalUser(const Signature::KeyPair &_keyPair, const std::string &name, Group *group) : User(name, group), keyPair(_keyPair) {} + private: + Signature::KeyPair keyPair; + }; +} diff --git a/include/odhtdb/Log.hpp b/include/odhtdb/Log.hpp new file mode 100644 index 0000000..d09c2a2 --- /dev/null +++ b/include/odhtdb/Log.hpp @@ -0,0 +1,12 @@ +#pragma once + +namespace odhtdb +{ + class Log + { + public: + static void debug(const char *fmt, ...); + static void warn(const char *fmt, ...); + static void error(const char *fmt, ...); + }; +} diff --git a/include/odhtdb/Permission.hpp b/include/odhtdb/Permission.hpp new file mode 100644 index 0000000..1ae2642 --- /dev/null +++ b/include/odhtdb/Permission.hpp @@ -0,0 +1,46 @@ +#pragma once + +#include "types.hpp" +#include <initializer_list> +#include <stdexcept> + +namespace odhtdb +{ + class PermissionDeniedException : public std::runtime_error + { + public: + PermissionDeniedException(const std::string &errMsg) : std::runtime_error(errMsg) {} + }; + + enum class PermissionType : u32 + { + ADD_DATA = (1 << 0), + ADD_USER_SAME_LEVEL = (1 << 1), + ADD_USER_LOWER_LEVEL = (1 << 2), + ADD_GROUP = (1 << 3), + REMOVE_GROUP = (1 << 4) + }; + + const PermissionType ALL_PERMISSION_TYPES = (PermissionType)0xFFFFFFFF; + + const u8 PERMISSION_LEVEL_ADMIN = 0; + const u8 PERMISSION_LEVEL_MODERATOR = 1; + const u8 PERMISSION_LEVEL_REGULAR_USER = 2; + + class Permission + { + public: + // @permissionLevel is hierarchical access right. A group can only modify a group that has higher @permissionLevel value + Permission(u8 permissionLevel, std::initializer_list<PermissionType> permissions); + + u8 getPermissionLevel() const { return permissionLevel; } + u32 getPermissionFlags() const { return permissionFlags; } + bool getFlag(PermissionType permissionType) const; + private: + u8 permissionLevel; + u32 permissionFlags; + }; + + static const Permission ADMIN_PERMISSION(PERMISSION_LEVEL_ADMIN, { ALL_PERMISSION_TYPES }); + static const Permission REGULAR_USER_PERMISSION(PERMISSION_LEVEL_REGULAR_USER, { PermissionType::ADD_DATA }); +} diff --git a/include/odhtdb/RemoteUser.hpp b/include/odhtdb/RemoteUser.hpp new file mode 100644 index 0000000..181a4c4 --- /dev/null +++ b/include/odhtdb/RemoteUser.hpp @@ -0,0 +1,24 @@ +#pragma once + +#include "User.hpp" + +namespace odhtdb +{ + class RemoteUser : public User + { + public: + static RemoteUser* create(const Signature::PublicKey &publicKey, const std::string &name, Group *group) + { + return new RemoteUser(publicKey, name, group); + } + + const Signature::PublicKey& getPublicKey() const override + { + return publicKey; + } + private: + RemoteUser(const Signature::PublicKey &_publicKey, const std::string &name, Group *group) : User(name, group), publicKey(_publicKey){} + private: + Signature::PublicKey publicKey; + }; +} diff --git a/include/odhtdb/Signature.hpp b/include/odhtdb/Signature.hpp new file mode 100644 index 0000000..62c41c3 --- /dev/null +++ b/include/odhtdb/Signature.hpp @@ -0,0 +1,126 @@ +#pragma once + +#include "DataView.hpp" +#include <stdexcept> +#include <unordered_map> + +namespace odhtdb +{ + const int PUBLIC_KEY_NUM_BYTES = 32; + const int PRIVATE_KEY_NUM_BYTES = 64; + const int SIGNED_HASH_SIZE = 64; + + class InvalidSignatureKeySize : public std::runtime_error + { + public: + InvalidSignatureKeySize(const std::string &errMsg) : std::runtime_error(errMsg) {} + }; + + class SignatureGenerationException : public std::runtime_error + { + public: + SignatureGenerationException(const std::string &errMsg) : std::runtime_error(errMsg) {} + }; + + class DataSignException : public std::runtime_error + { + public: + DataSignException(const std::string &errMsg) : std::runtime_error(errMsg) {} + }; + + class UnsignException : public std::runtime_error + { + public: + UnsignException(const std::string &errMsg) : std::runtime_error(errMsg) {} + virtual ~UnsignException(){} + }; + + class UnsignInvalidSizeException : public UnsignException + { + public: + UnsignInvalidSizeException(const std::string &errMsg) : UnsignException(errMsg) {} + }; + + class UnsignWrongKeyException : public UnsignException + { + public: + UnsignWrongKeyException(const std::string &errMsg) : UnsignException(errMsg) {} + }; + + namespace Signature + { + class PublicKey + { + friend class KeyPair; + public: + static PublicKey ZERO; + + // Throws InvalidSignatureKeySize if size is not PUBLIC_KEY_NUM_BYTES + PublicKey(const char *data, size_t size); + PublicKey(const PublicKey &other); + PublicKey& operator=(const PublicKey &other); + + const char* getData() const { return data; } + size_t getSize() const { return PUBLIC_KEY_NUM_BYTES; } + + // Throws UnsignWrongKeyException if signed message was not signed using the matching private key of this public key. + // Throws UnsignInvalidSizeException if signed message is too small (< SIGNED_HASH_SIZE). + // Both exceptions are derived from UnsignException + std::string unsign(const DataView &signedMessage) const; + + size_t operator()() const; + bool operator==(const PublicKey &other) const; + + std::string toString() const; + private: + PublicKey(){} + private: + char data[PUBLIC_KEY_NUM_BYTES]; + }; + + struct PublicKeyHasher + { + size_t operator()(const PublicKey &publicKey) const + { + return publicKey(); + } + }; + + template <typename ValueType> + using MapPublicKey = std::unordered_map<PublicKey, ValueType, PublicKeyHasher>; + + class PrivateKey + { + friend class KeyPair; + public: + // Throws InvalidSignatureKeySize if size is not PRIVATE_KEY_NUM_BYTES + PrivateKey(const char *data, size_t size); + PrivateKey(const PrivateKey &other); + PrivateKey& operator=(const PrivateKey &other); + + const char* getData() const { return data; } + size_t getSize() const { return PRIVATE_KEY_NUM_BYTES; } + + // Throws DataSignException if signing data failed for whatever reason. This wont happen unless there is an issue with the private key + std::string sign(const DataView &dataToSign) const; + std::string toString() const; + private: + PrivateKey(){} + private: + char data[PRIVATE_KEY_NUM_BYTES]; + }; + + class KeyPair + { + public: + // Throws SignatureGenerationException if generation of private/public key pair fails (should never happen) + KeyPair(); + + const PublicKey& getPublicKey() const { return publicKey; } + const PrivateKey& getPrivateKey() const { return privateKey; } + private: + PublicKey publicKey; + PrivateKey privateKey; + }; + } +} diff --git a/include/odhtdb/StagedObject.hpp b/include/odhtdb/StagedObject.hpp new file mode 100644 index 0000000..0c9b534 --- /dev/null +++ b/include/odhtdb/StagedObject.hpp @@ -0,0 +1,22 @@ +#pragma once + +#include "utils.hpp" +#include "Hash.hpp" +#include "DataView.hpp" + +namespace odhtdb +{ + struct StagedObject + { + DISABLE_COPY(StagedObject) + DataView data; + std::shared_ptr<Hash> requestKey; + + StagedObject(DataView &_data, const std::shared_ptr<Hash> &_requestKey) : + data(_data), + requestKey(_requestKey) + { + + } + }; +} diff --git a/include/odhtdb/User.hpp b/include/odhtdb/User.hpp new file mode 100644 index 0000000..fb37876 --- /dev/null +++ b/include/odhtdb/User.hpp @@ -0,0 +1,38 @@ +#pragma once + +#include "Signature.hpp" +#include <string> +#include <stdexcept> +#include <vector> + +namespace odhtdb +{ + class Group; + + class UserNameTooLongException : public std::runtime_error + { + public: + UserNameTooLongException(const std::string &userName) : + std::runtime_error(std::string("The username ") + userName + " is longer than 255 bytes") + { + + } + }; + + class User + { + public: + virtual ~User(){} + + void addToGroup(Group *group); + + const std::string& getName() const { return name; } + const std::vector<Group*>& getGroups() const { return groups; } + virtual const Signature::PublicKey& getPublicKey() const = 0; + protected: + User(const std::string &name, Group *group); + private: + std::string name; + std::vector<Group*> groups; + }; +} diff --git a/include/odhtdb/bin2hex.hpp b/include/odhtdb/bin2hex.hpp new file mode 100644 index 0000000..72b57c1 --- /dev/null +++ b/include/odhtdb/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; + } +} diff --git a/include/odhtdb/types.hpp b/include/odhtdb/types.hpp new file mode 100644 index 0000000..3cf7f02 --- /dev/null +++ b/include/odhtdb/types.hpp @@ -0,0 +1,22 @@ +#pragma once + +#include <cstdint> + +namespace odhtdb +{ + typedef int8_t i8; + typedef int16_t i16; + typedef int32_t i32; + typedef int64_t i64; + + typedef uint8_t u8; + typedef uint16_t u16; + typedef uint32_t u32; + typedef uint64_t u64; + + typedef float f32; + typedef double f64; + + typedef intptr_t isize; + typedef uintptr_t usize; +} diff --git a/include/odhtdb/utils.hpp b/include/odhtdb/utils.hpp new file mode 100755 index 0000000..01e478d --- /dev/null +++ b/include/odhtdb/utils.hpp @@ -0,0 +1,6 @@ +#pragma once + +// Disable copying for a class or struct +#define DISABLE_COPY(ClassName) \ + ClassName(ClassName&) = delete; \ + ClassName& operator = (ClassName&) = delete; |