forked from blue/squawk
feat: omemo signal lib wip
This commit is contained in:
parent
08fe37bfb2
commit
442ad37300
34 changed files with 745 additions and 262 deletions
|
@ -1,6 +1,8 @@
|
|||
target_sources(squawk PRIVATE
|
||||
context.cpp
|
||||
context.h
|
||||
util.cpp
|
||||
util.h
|
||||
)
|
||||
|
||||
add_subdirectory(crypto)
|
||||
|
|
|
@ -4,6 +4,19 @@
|
|||
|
||||
#include "context.h"
|
||||
|
||||
Signal::Context::Context() {}
|
||||
using namespace Signal;
|
||||
|
||||
Signal::Context::~Context() {}
|
||||
Context::Context() {}
|
||||
|
||||
Context::~Context() {}
|
||||
|
||||
std::unique_ptr<Crypto::ECKeyPair> Context::generateCurveKeyPair() {
|
||||
auto result = std::unique_ptr<Crypto::ECKeyPair>();
|
||||
// TODO
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
signal_context *Context::temporaryGetContextUnsafeForRawAccessThatNeedsToBeWrapped() {
|
||||
return ctx;
|
||||
}
|
||||
|
|
|
@ -4,6 +4,10 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
#include "crypto/ec.h"
|
||||
|
||||
#include <memory>
|
||||
|
||||
#include <signal/signal_protocol.h>
|
||||
|
||||
namespace Signal {
|
||||
|
@ -16,6 +20,10 @@ namespace Signal {
|
|||
Context(Context &&) = delete;
|
||||
Context &operator=(const Context &) = delete;
|
||||
|
||||
std::unique_ptr<Crypto::ECKeyPair> generateCurveKeyPair();
|
||||
|
||||
signal_context *temporaryGetContextUnsafeForRawAccessThatNeedsToBeWrapped();
|
||||
|
||||
private:
|
||||
signal_context *ctx{nullptr};
|
||||
};
|
||||
|
|
|
@ -7,4 +7,6 @@ target_sources(squawk PRIVATE
|
|||
hmac_sha256_openssl.h
|
||||
sha512_digest_openssl.cpp
|
||||
sha512_digest_openssl.h
|
||||
ec.cpp
|
||||
ec.h
|
||||
)
|
||||
|
|
5
qomemo/signal/crypto/ec.cpp
Normal file
5
qomemo/signal/crypto/ec.cpp
Normal file
|
@ -0,0 +1,5 @@
|
|||
/*
|
||||
* Created by victoria on 2021-06-17.
|
||||
*/
|
||||
|
||||
#include "ec.h"
|
20
qomemo/signal/crypto/ec.h
Normal file
20
qomemo/signal/crypto/ec.h
Normal file
|
@ -0,0 +1,20 @@
|
|||
/*
|
||||
* Created by victoria on 2021-06-17.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <signal/signal_protocol.h>
|
||||
|
||||
namespace Signal::Crypto {
|
||||
|
||||
class ECKeyPair {
|
||||
public:
|
||||
ECKeyPair();
|
||||
~ECKeyPair();
|
||||
|
||||
private:
|
||||
ec_key_pair *ec;
|
||||
};
|
||||
|
||||
}
|
|
@ -4,13 +4,56 @@
|
|||
|
||||
#include "identity_key_store.h"
|
||||
|
||||
void Signal::Store::IdentityKeyStore::boundToContext(
|
||||
signal_protocol_store_context *ctx) {
|
||||
signal_protocol_identity_key_store store{};
|
||||
#include "qomemo/signal/util.h"
|
||||
#include <utility>
|
||||
|
||||
store.user_data = nullptr;
|
||||
store.destroy_func = nullptr;
|
||||
Signal::Store::IdentityKeyStore::IdentityKeyStore(QXmpp::Omemo::DeviceService &deviceService, QString jid, int deviceId)
|
||||
: jid(std::move(jid)), deviceId(deviceId), deviceService(deviceService) {
|
||||
database = deviceService.getDatabase(jid);
|
||||
}
|
||||
|
||||
int Signal::Store::IdentityKeyStore::getIdentityKeyPair(signal_buffer **public_data, signal_buffer **private_data) {
|
||||
auto pk = database->loadIdentityKey(deviceId);
|
||||
auto sk = database->loadIdentityKeySecret(deviceId);
|
||||
|
||||
*public_data = signal_buffer_create(reinterpret_cast<const uint8_t *>(pk->data()), pk->size());
|
||||
*private_data = signal_buffer_create(reinterpret_cast<const uint8_t *>(sk->data()), sk->size());
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int Signal::Store::IdentityKeyStore::getLocalRegistrationId(uint32_t *registration_id) {
|
||||
// TODO: Figure out what registration id is used for
|
||||
*registration_id = 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int Signal::Store::IdentityKeyStore::saveIdentity(const signal_protocol_address *address, uint8_t *key_data,
|
||||
size_t key_len) {
|
||||
auto identityJid = Signal::Util::jidFromAddress(address);
|
||||
auto identityKey = Signal::Util::byteArray(key_data, key_len);
|
||||
|
||||
deviceService.getDatabase(identityJid)->saveIdentityKey(address->device_id, identityKey);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int Signal::Store::IdentityKeyStore::isTrustedIdentity(const signal_protocol_address *address, uint8_t *key_data,
|
||||
size_t key_len) {
|
||||
auto identityJid = Signal::Util::jidFromAddress(address);
|
||||
auto actualIdentityKey = deviceService.getDatabase(identityJid)->loadIdentityKey(address->device_id);
|
||||
|
||||
if (!actualIdentityKey.has_value()) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
auto givenIdentityKey = Signal::Util::byteArray(key_data, key_len);
|
||||
|
||||
return givenIdentityKey == actualIdentityKey ? 1 : 0;
|
||||
}
|
||||
|
||||
void Signal::Store::IdentityKeyStore::fillCallbacks(signal_protocol_identity_key_store &store) {
|
||||
store.get_identity_key_pair = [](signal_buffer **public_data, signal_buffer **private_data, void *ptr) {
|
||||
return static_cast<IdentityKeyStore *>(ptr)->getIdentityKeyPair(public_data, private_data);
|
||||
};
|
||||
|
@ -24,24 +67,4 @@ void Signal::Store::IdentityKeyStore::boundToContext(
|
|||
store.save_identity = [](const signal_protocol_address *address, uint8_t *key_data, size_t key_len, void *ptr) {
|
||||
return static_cast<IdentityKeyStore *>(ptr)->saveIdentity(address, key_data, key_len);
|
||||
};
|
||||
|
||||
signal_protocol_store_context_set_identity_key_store(ctx, &store);
|
||||
}
|
||||
|
||||
int Signal::Store::IdentityKeyStore::getIdentityKeyPair(signal_buffer **public_data, signal_buffer **private_data) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
int Signal::Store::IdentityKeyStore::getLocalRegistrationId(uint32_t *registration_id) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
int Signal::Store::IdentityKeyStore::saveIdentity(const signal_protocol_address *address, uint8_t *key_data,
|
||||
size_t key_len) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
int Signal::Store::IdentityKeyStore::isTrustedIdentity(const signal_protocol_address *address, uint8_t *key_data,
|
||||
size_t key_len) {
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -6,16 +6,27 @@
|
|||
|
||||
#include <signal/signal_protocol.h>
|
||||
|
||||
#include "qomemo/device_service.h"
|
||||
|
||||
namespace Signal::Store {
|
||||
|
||||
class IdentityKeyStore {
|
||||
public:
|
||||
static void boundToContext(signal_protocol_store_context *ctx);
|
||||
IdentityKeyStore(QXmpp::Omemo::DeviceService &deviceService, QString jid, int deviceId);
|
||||
|
||||
int getIdentityKeyPair(signal_buffer **public_data, signal_buffer **private_data);
|
||||
int getLocalRegistrationId(uint32_t *registration_id);
|
||||
int saveIdentity(const signal_protocol_address *address, uint8_t *key_data, size_t key_len);
|
||||
int isTrustedIdentity(const signal_protocol_address *address, uint8_t *key_data, size_t key_len);
|
||||
|
||||
void fillCallbacks(signal_protocol_identity_key_store &store);
|
||||
|
||||
const QString jid;
|
||||
const int deviceId;
|
||||
|
||||
private:
|
||||
QXmpp::Omemo::DeviceService &deviceService;
|
||||
QSharedPointer<QXmpp::Omemo::Database> database;
|
||||
};
|
||||
|
||||
} // namespace Signal::Store
|
||||
|
|
|
@ -4,29 +4,8 @@
|
|||
|
||||
#include "pre_key_store.h"
|
||||
|
||||
void Signal::Store::PreKeyStore::boundToContext(
|
||||
signal_protocol_store_context *ctx) {
|
||||
signal_protocol_pre_key_store store{};
|
||||
|
||||
store.destroy_func = nullptr;
|
||||
store.user_data = nullptr;
|
||||
|
||||
store.contains_pre_key = [](uint32_t id, void *ptr) {
|
||||
return static_cast<PreKeyStore *>(ptr)->containsPreKey(id);
|
||||
};
|
||||
store.load_pre_key = [](signal_buffer **record, uint32_t id, void *ptr) {
|
||||
return static_cast<PreKeyStore *>(ptr)->loadPreKey(record, id);
|
||||
};
|
||||
store.remove_pre_key = [](uint32_t id, void *ptr) {
|
||||
return static_cast<PreKeyStore *>(ptr)->removePreKey(id);
|
||||
};
|
||||
store.store_pre_key = [](uint32_t id, uint8_t *record, size_t size,
|
||||
void *ptr) {
|
||||
return static_cast<PreKeyStore *>(ptr)->storePreKey(id, record, size);
|
||||
};
|
||||
|
||||
signal_protocol_store_context_set_pre_key_store(ctx, &store);
|
||||
}
|
||||
Signal::Store::PreKeyStore::PreKeyStore(QSharedPointer<QXmpp::Omemo::Database> database) : database(
|
||||
std::move(database)) {}
|
||||
|
||||
int Signal::Store::PreKeyStore::containsPreKey(uint32_t pre_key_id) {
|
||||
return 0;
|
||||
|
@ -41,3 +20,19 @@ int Signal::Store::PreKeyStore::storePreKey(uint32_t pre_key_id, uint8_t *record
|
|||
}
|
||||
|
||||
int Signal::Store::PreKeyStore::removePreKey(uint32_t pre_key_id) { return 0; }
|
||||
|
||||
void Signal::Store::PreKeyStore::fillCallbacks(signal_protocol_pre_key_store &store) {
|
||||
store.contains_pre_key = [](uint32_t id, void *ptr) {
|
||||
return static_cast<PreKeyStore *>(ptr)->containsPreKey(id);
|
||||
};
|
||||
store.load_pre_key = [](signal_buffer **record, uint32_t id, void *ptr) {
|
||||
return static_cast<PreKeyStore *>(ptr)->loadPreKey(record, id);
|
||||
};
|
||||
store.remove_pre_key = [](uint32_t id, void *ptr) {
|
||||
return static_cast<PreKeyStore *>(ptr)->removePreKey(id);
|
||||
};
|
||||
store.store_pre_key = [](uint32_t id, uint8_t *record, size_t size,
|
||||
void *ptr) {
|
||||
return static_cast<PreKeyStore *>(ptr)->storePreKey(id, record, size);
|
||||
};
|
||||
}
|
||||
|
|
|
@ -6,16 +6,23 @@
|
|||
|
||||
#include <signal/signal_protocol.h>
|
||||
|
||||
#include "qomemo/device_service.h"
|
||||
|
||||
namespace Signal::Store {
|
||||
|
||||
class PreKeyStore {
|
||||
public:
|
||||
static void boundToContext(signal_protocol_store_context *ctx);
|
||||
explicit PreKeyStore(QSharedPointer<QXmpp::Omemo::Database> database);
|
||||
|
||||
int containsPreKey(uint32_t pre_key_id);
|
||||
int loadPreKey(signal_buffer **record, uint32_t pre_key_id);
|
||||
int storePreKey(uint32_t pre_key_id, uint8_t *record, size_t record_len);
|
||||
int removePreKey(uint32_t pre_key_id);
|
||||
|
||||
void fillCallbacks(signal_protocol_pre_key_store &store);
|
||||
|
||||
private:
|
||||
QSharedPointer<QXmpp::Omemo::Database> database;
|
||||
};
|
||||
|
||||
} // namespace Signal::Store
|
||||
|
|
14
qomemo/signal/util.cpp
Normal file
14
qomemo/signal/util.cpp
Normal file
|
@ -0,0 +1,14 @@
|
|||
/*
|
||||
* Created by victoria on 2021-05-15.
|
||||
*/
|
||||
|
||||
#include "util.h"
|
||||
|
||||
QString Signal::Util::jidFromAddress(const signal_protocol_address *address) {
|
||||
// TODO: Validate this
|
||||
return QString::fromRawData(reinterpret_cast<const QChar *>(address->name), static_cast<int>(address->name_len));
|
||||
}
|
||||
|
||||
QByteArray Signal::Util::byteArray(const uint8_t *data, size_t len) {
|
||||
return QByteArray::fromRawData(reinterpret_cast<const char *>(data), static_cast<int>(len));
|
||||
}
|
18
qomemo/signal/util.h
Normal file
18
qomemo/signal/util.h
Normal file
|
@ -0,0 +1,18 @@
|
|||
/*
|
||||
* Created by victoria on 2021-05-15.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <signal/signal_protocol.h>
|
||||
|
||||
#include <QString>
|
||||
#include <QByteArray>
|
||||
|
||||
namespace Signal::Util {
|
||||
|
||||
QString jidFromAddress(const signal_protocol_address *address);
|
||||
|
||||
QByteArray byteArray(const uint8_t *data, size_t len);
|
||||
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue