From 67957afb6ba01bcd85f1abd1a50ad2c1aa813c7c Mon Sep 17 00:00:00 2001 From: Aleksi Lindeman <0xdec05eba@gmail.com> Date: Wed, 14 Feb 2018 22:18:48 +0100 Subject: Sign messages/verify message signatures --- src/Database.cpp | 39 +++++++++++++++++++++++++-------------- src/Signature.cpp | 19 ++++++++++++++++--- 2 files changed, 41 insertions(+), 17 deletions(-) (limited to 'src') diff --git a/src/Database.cpp b/src/Database.cpp index e3b9f3d..90e83c1 100644 --- a/src/Database.cpp +++ b/src/Database.cpp @@ -85,18 +85,21 @@ namespace odhtdb node.listen(ADD_DATA_HASH, bind(&Database::listenAddData, this, _1)); } - void Database::create(const Key &key, Group *primaryAdminGroup) + void Database::create(LocalUser *owner, const Key &key) { + Group *primaryAdminGroup = new Group("admin"); + primaryAdminGroup->addUser(owner); // TODO: Append fractions to get real microseconds time u64 timeMicroseconds = ((u64)getSyncedTimestampUtc().seconds) * 1000000ull; stagedCreateObjects.emplace_back(StagedCreateObject(key, primaryAdminGroup, timeMicroseconds)); } - void Database::add(const Key &key, DataView data, LocalUser *creator) + void Database::add(LocalUser *owner, const Key &key, DataView data) { + unique_ptr signedData = make_unique(owner->getPrivateKey().sign(data)); // TODO: Append fractions to get real microseconds time u64 timeMicroseconds = ((u64)getSyncedTimestampUtc().seconds) * 1000000ull; - stagedAddObjects.emplace_back(StagedAddObject(key, data, timeMicroseconds, creator->getPublicKey())); + stagedAddObjects.emplace_back(StagedAddObject(key, move(signedData), timeMicroseconds, owner->getPublicKey())); } void Database::commit() @@ -108,6 +111,7 @@ namespace odhtdb for(StagedCreateObject &stagedObject : stagedCreateObjects) { commitStagedCreateObject(stagedObject); + delete stagedObject.primaryAdminGroup; } stagedCreateObjects.clear(); @@ -177,9 +181,9 @@ namespace odhtdb serializer.add(stagedObject.key.hashedKey.data(), OPENDHT_INFOHASH_LEN); serializer.add(stagedObject.timestamp); serializer.add((u8*)stagedObject.creatorPublicKey.getData(), PUBLIC_KEY_NUM_BYTES); - assert(stagedObject.data.size < 0xFFFF - 120); - serializer.add((u16)stagedObject.data.size); - serializer.add((u8*)stagedObject.data.data, stagedObject.data.size); + assert(stagedObject.data->size() < 0xFFFF - 120); + serializer.add((u16)stagedObject.data->size()); + serializer.add((u8*)stagedObject.data->data(), stagedObject.data->size()); // TODO: Verify if serializer buffer needs to survive longer than this scope Value addDataValue(serializer.getBuffer().data(), serializer.getBuffer().size()); @@ -262,11 +266,15 @@ namespace odhtdb Signature::PublicKey creatorPublicKey(creatorPublicKeyRaw, PUBLIC_KEY_NUM_BYTES); u16 dataSize = deserializer.extract(); - char *data = (char*)malloc(dataSize); - if(!data) - throw sibs::DeserializeException("Failed to allocate memory for add request"); - result.data.data = data; - result.data.size = dataSize; + if(dataSize < SIGNED_HASH_SIZE) + throw sibs::DeserializeException("Signed data is too small"); + + string signedData; + signedData.resize(dataSize); + deserializer.extract((u8*)&signedData[0], dataSize); + result.data = make_unique(); + result.data->resize(dataSize); + result.data = make_unique(creatorPublicKey.unsign(DataView((void*)signedData.data(), signedData.size()))); return result; } @@ -279,7 +287,6 @@ namespace odhtdb // TODO: Verify createObject timestamp is not in the future StagedCreateObject createObject = deserializeCreateRequest(value); databaseStorage.createStorage(createObject.key, { createObject.primaryAdminGroup }, createObject.timestamp); - //delete createObject.primaryAdminGroup; } catch (sibs::DeserializeException &e) { @@ -299,8 +306,8 @@ namespace odhtdb { // TODO: Verify createObject timestamp is not in the future StagedAddObject addObject = deserializeAddRequest(value); - databaseStorage.appendStorage(addObject.key, addObject.data, addObject.timestamp, addObject.creatorPublicKey); - //free(addObject.data.data); + DataView data((void*)addObject.data->data(), addObject.data->size()); + databaseStorage.appendStorage(addObject.key, data, addObject.timestamp, addObject.creatorPublicKey); } catch (sibs::DeserializeException &e) { @@ -310,6 +317,10 @@ namespace odhtdb { fprintf(stderr, "Warning: Failed to deserialize 'add' request: %s\n", e.what()); } + catch (UnsignException &e) + { + fprintf(stderr, "Warning: Failed to deserialize 'add' request: %s\n", e.what()); + } return true; } } diff --git a/src/Signature.cpp b/src/Signature.cpp index 946d754..8d3654d 100644 --- a/src/Signature.cpp +++ b/src/Signature.cpp @@ -35,6 +35,19 @@ namespace odhtdb return *this; } + string PublicKey::unsign(const DataView &signedMessage) const + { + if(signedMessage.size < SIGNED_HASH_SIZE) + throw UnsignInvalidSizeException("Signed message is too small (corrupt or malicious signed message)"); + + string result; + result.resize(signedMessage.size - SIGNED_HASH_SIZE); + if(crypto_sign_ed25519_open((unsigned char*)&result[0], nullptr, (const unsigned char*)signedMessage.data, signedMessage.size, (unsigned char*)data) != 0) + throw UnsignWrongKeyException("Message was not signed with matching private key"); + + return result; + } + string PublicKey::toString() const { string result; @@ -67,13 +80,13 @@ namespace odhtdb return *this; } - string PrivateKey::sign(const string &dataToSign) const + string PrivateKey::sign(const DataView &dataToSign) const { string result; - result.resize(crypto_sign_ed25519_BYTES + dataToSign.size()); + 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) + 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()) -- cgit v1.2.3