aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authordec05eba <dec05eba@protonmail.com>2018-02-10 03:38:47 +0100
committerdec05eba <dec05eba@protonmail.com>2020-08-18 23:25:12 +0200
commita19e68b9b029d5374604e4b81dcff161d4b465ba (patch)
treef1401a0278bd82deff117279376beec761e60a55 /src
parent5c1a20c4dacfe03db90b70c2665e66a76574196c (diff)
Add private/public key for users
Diffstat (limited to 'src')
-rw-r--r--src/Database.cpp66
-rw-r--r--src/Signature.cpp97
2 files changed, 153 insertions, 10 deletions
diff --git a/src/Database.cpp b/src/Database.cpp
index c2d08cb..f0c7b04 100644
--- a/src/Database.cpp
+++ b/src/Database.cpp
@@ -1,6 +1,7 @@
#include "../include/Database.hpp"
#include "../include/Group.hpp"
-#include "../include/User.hpp"
+#include "../include/LocalUser.hpp"
+#include "../include/RemoteUser.hpp"
#include <opendht.h>
#include <fmt/format.h>
#include <sodium/crypto_box_curve25519xchacha20poly1305.h>
@@ -22,11 +23,11 @@ static bool timestampSynced = false;
static InfoHash CREATE_DATA_HASH = InfoHash::get("__odhtdb__.create_data");
static InfoHash ADD_DATA_HASH = InfoHash::get("__odhtdb__.add_data");
-#define OPENDHT_INFOHASH_LEN 20
+const int OPENDHT_INFOHASH_LEN = 20;
namespace odhtdb
{
- Database::Database(const char *bootstrapNodeAddr, u16 port)
+ Database::Database(const char *bootstrapNodeAddr, u16 port, boost::filesystem::path storageDir)
{
node.run(port, dht::crypto::generateIdentity(), true);
fmt::MemoryWriter portStr;
@@ -126,21 +127,32 @@ namespace odhtdb
serializer.add(stagedObject.timestamp);
serializer.add((u8)stagedObject.primaryAdminGroup->getName().size());
serializer.add((u8*)stagedObject.primaryAdminGroup->getName().data(), stagedObject.primaryAdminGroup->getName().size());
- serializer.add((u32)stagedObject.primaryAdminGroup->getUsers().size());
+ assert(stagedObject.primaryAdminGroup->getUsers().size() <= 255);
+ serializer.add((u8)stagedObject.primaryAdminGroup->getUsers().size());
for(User *user : stagedObject.primaryAdminGroup->getUsers())
{
+ serializer.add((u8*)user->getPublicKey().getData(), PUBLIC_KEY_NUM_BYTES);
serializer.add((u8)user->getName().size());
serializer.add((u8*)user->getName().data(), user->getName().size());
}
// TODO: Verify if serializer buffer needs to survive longer than this scope
- Value value(serializer.getBuffer().data(), serializer.getBuffer().size());
- node.put(CREATE_DATA_HASH, move(value), [](bool ok)
+ Value createDataValue(serializer.getBuffer().data(), serializer.getBuffer().size());
+ node.put(CREATE_DATA_HASH, move(createDataValue), [](bool ok)
{
// TODO: Handle failure to put data
if(!ok)
fprintf(stderr, "Failed to put: %s, what to do?\n", "commitStagedCreateObject");
}, time_point(), false);
+
+ // Post data for listeners of this key
+ Value putKeyValue(serializer.getBuffer().data() + OPENDHT_INFOHASH_LEN, serializer.getBuffer().size() - OPENDHT_INFOHASH_LEN);
+ node.put(stagedObject.key.hashedKey, move(putKeyValue), [](bool ok)
+ {
+ // TODO: Handle failure to put data
+ if(!ok)
+ fprintf(stderr, "Failed to put for listeners: %s, what to do?\n", "commitStagedCreateObject");
+ }, time_point(), false);
}
void Database::commitStagedAddObject(const StagedAddObject &stagedObject)
@@ -154,12 +166,21 @@ namespace odhtdb
serializer.add((u8*)stagedObject.data.data, stagedObject.data.size);
// TODO: Verify if serializer buffer needs to survive longer than this scope
- Value value(serializer.getBuffer().data(), serializer.getBuffer().size());
- node.put(ADD_DATA_HASH, move(value), [](bool ok)
+ Value addDataValue(serializer.getBuffer().data(), serializer.getBuffer().size());
+ node.put(ADD_DATA_HASH, move(addDataValue), [](bool ok)
+ {
+ // TODO: Handle failure to put data
+ if(!ok)
+ fprintf(stderr, "Failed to put for all: %s, what to do?\n", "commitStagedAddObject");
+ }, time_point(), false);
+
+ // Post data for listeners of this key
+ Value putKeyValue(serializer.getBuffer().data() + OPENDHT_INFOHASH_LEN, serializer.getBuffer().size() - OPENDHT_INFOHASH_LEN);
+ node.put(stagedObject.key.hashedKey, move(putKeyValue), [](bool ok)
{
// TODO: Handle failure to put data
if(!ok)
- fprintf(stderr, "Failed to put: %s, what to do?\n", "commitStagedAddObject");
+ fprintf(stderr, "Failed to put for listeners: %s, what to do?\n", "commitStagedAddObject");
}, time_point(), false);
}
@@ -182,6 +203,29 @@ namespace odhtdb
result.key.hashedKey = InfoHash(entryKeyRaw, OPENDHT_INFOHASH_LEN);
result.timestamp = deserializer.extract<u64>();
+ u8 adminGroupNameSize = deserializer.extract<u8>();
+ string adminGroupName;
+ adminGroupName.resize(adminGroupNameSize);
+ deserializer.extract((u8*)&adminGroupName[0], adminGroupNameSize);
+ result.primaryAdminGroup = new Group(adminGroupName);
+
+ u8 numUsers = deserializer.extract<u8>();
+ for(int i = 0; i < numUsers; ++i)
+ {
+ char userPublicKeyRaw[PUBLIC_KEY_NUM_BYTES];
+ deserializer.extract((u8*)userPublicKeyRaw, PUBLIC_KEY_NUM_BYTES);
+ Signature::PublicKey userPublicKey(userPublicKeyRaw, PUBLIC_KEY_NUM_BYTES);
+
+ u8 userNameSize = deserializer.extract<u8>();
+ string userName;
+ userName.resize(userNameSize);
+ deserializer.extract((u8*)&userName[0], userNameSize);
+
+ RemoteUser *user = RemoteUser::create(userPublicKey, userName);
+ result.primaryAdminGroup->addUser(user);
+ }
+
+ // NOTE: There might be more data in deserializer, but we can ignore those; we already got all data we need
return result;
}
@@ -204,7 +248,9 @@ namespace odhtdb
{
try
{
+ // TODO: Verify createObject timestamp is not in the future
StagedCreateObject createObject = deserializeCreateRequest(value);
+ delete createObject.primaryAdminGroup;
}
catch (sibs::DeserializeException &e)
{
@@ -229,4 +275,4 @@ namespace odhtdb
}
return true;
}
-} \ No newline at end of file
+}
diff --git a/src/Signature.cpp b/src/Signature.cpp
new file mode 100644
index 0000000..804047e
--- /dev/null
+++ b/src/Signature.cpp
@@ -0,0 +1,97 @@
+#include "../include/Signature.hpp"
+#include <sodium/crypto_sign_ed25519.h>
+#include <sodium/utils.h>
+#include <cstring>
+
+using namespace std;
+
+namespace odhtdb
+{
+ namespace Signature
+ {
+ PublicKey::PublicKey(char *_data, size_t size)
+ {
+ if(size != PUBLIC_KEY_NUM_BYTES)
+ {
+ string errMsg = "Expected public key size to be ";
+ errMsg += to_string(PUBLIC_KEY_NUM_BYTES);
+ errMsg += " bytes, was: ";
+ errMsg += to_string(size);
+ throw InvalidSignatureKeySize(errMsg);
+ }
+ memmove(data, _data, PUBLIC_KEY_NUM_BYTES);
+ }
+
+ PublicKey::PublicKey(const PublicKey &other)
+ {
+ memmove(data, other.data, PUBLIC_KEY_NUM_BYTES);
+ }
+
+ PublicKey& PublicKey::operator=(const PublicKey &other)
+ {
+ memmove(data, other.data, PUBLIC_KEY_NUM_BYTES);
+ return *this;
+ }
+
+ string PublicKey::toString() const
+ {
+ string result;
+ result.resize(PUBLIC_KEY_NUM_BYTES * 2);
+ sodium_bin2hex(&result[0], PUBLIC_KEY_NUM_BYTES * 2 + 1, (const unsigned char*)data, PUBLIC_KEY_NUM_BYTES);
+ return result;
+ }
+
+ PrivateKey::PrivateKey(char *_data, size_t size)
+ {
+ if(size != PRIVATE_KEY_NUM_BYTES)
+ {
+ string errMsg = "Expected private key size to be ";
+ errMsg += to_string(PRIVATE_KEY_NUM_BYTES);
+ errMsg += " bytes, was: ";
+ errMsg += to_string(size);
+ throw InvalidSignatureKeySize(errMsg);
+ }
+ memmove(data, _data, PRIVATE_KEY_NUM_BYTES);
+ }
+
+ PrivateKey::PrivateKey(const PrivateKey &other)
+ {
+ memmove(data, other.data, PRIVATE_KEY_NUM_BYTES);
+ }
+
+ PrivateKey& PrivateKey::operator=(const PrivateKey &other)
+ {
+ memmove(data, other.data, PRIVATE_KEY_NUM_BYTES);
+ return *this;
+ }
+
+ string PrivateKey::sign(const string &dataToSign) const
+ {
+ string result;
+ result.resize(crypto_sign_ed25519_BYTES + dataToSign.size());
+ unsigned long long resultSize;
+
+ if(crypto_sign_ed25519((unsigned char*)&result[0], &resultSize, (unsigned char*)dataToSign.data(), dataToSign.size(), (unsigned char*)data) != 0)
+ throw DataSignException("Failed to sign data. Is private key invalid?");
+
+ if(resultSize != result.size())
+ throw DataSignException("Failed to sign data. The signed data is not of expected size (bug)");
+
+ return result;
+ }
+
+ string PrivateKey::toString() const
+ {
+ string result;
+ result.resize(PRIVATE_KEY_NUM_BYTES * 2);
+ sodium_bin2hex(&result[0], PRIVATE_KEY_NUM_BYTES * 2 + 1, (const unsigned char*)data, PRIVATE_KEY_NUM_BYTES);
+ return result;
+ }
+
+ KeyPair::KeyPair()
+ {
+ if(crypto_sign_ed25519_keypair((unsigned char*)publicKey.data, (unsigned char*)privateKey.data) != 0)
+ throw SignatureGenerationException("Failed to generate signature keypair");
+ }
+ }
+}