feat(omemo): add signal protocol wrappers

This commit is contained in:
vae 2021-05-13 17:50:29 +03:00
parent 12ffe8e8e6
commit 2654e38665
Signed by: vae
GPG Key ID: A9A33351400E00E5
28 changed files with 874 additions and 27 deletions

View File

@ -1,14 +1,14 @@
target_sources(squawk PRIVATE target_sources(squawk PRIVATE
bundle.cpp bundle.cpp
bundle.h bundle.h
database.cpp
database.h
device.cpp device.cpp
device.h device.h
device_key_storage.cpp device_key_storage.cpp
device_key_storage.h device_key_storage.h
device_service.cpp device_service.cpp
device_service.h device_service.h
signal.h
signal.cpp
qomemo.cpp qomemo.cpp
qomemo.h qomemo.h
sce.cpp sce.cpp
@ -19,4 +19,5 @@ target_sources(squawk PRIVATE
qxmpp_omemo_manager.h qxmpp_omemo_manager.h
) )
add_subdirectory(signal)
add_subdirectory(variant) add_subdirectory(variant)

View File

@ -1,5 +0,0 @@
/*
* Created by victoria on 2021-05-11.
*/
#include "signal.h"

View File

@ -1,20 +0,0 @@
/*
* Created by victoria on 2021-05-11.
*/
#pragma once
#include <signal/signal_protocol.h>
namespace Signal
{
class Context {};
class RatchetIdentityPair {};
class SessionSignedPreKey {};
class ProtocolKeyHelper {};
class ProtocolStoreContext {};
class SessionBuilder {};
class SessionCipher {};
}

View File

@ -0,0 +1,7 @@
target_sources(squawk PRIVATE
context.cpp
context.h
)
add_subdirectory(crypto)
add_subdirectory(stores)

View File

@ -0,0 +1,9 @@
/*
* Created by victoria on 2021-05-13.
*/
#include "context.h"
Signal::Context::Context() {}
Signal::Context::~Context() {}

23
qomemo/signal/context.h Normal file
View File

@ -0,0 +1,23 @@
/*
* Created by victoria on 2021-05-13.
*/
#pragma once
#include <signal/signal_protocol.h>
namespace Signal {
class Context {
public:
Context();
~Context();
Context(const Context &) = delete;
Context(Context &&) = delete;
Context &operator=(const Context &) = delete;
private:
signal_context *ctx{nullptr};
};
} // namespace Signal

View File

@ -0,0 +1,10 @@
target_sources(squawk PRIVATE
aes_openssl.cpp
aes_openssl.h
crypto.cpp
crypto.h
hmac_sha256_openssl.cpp
hmac_sha256_openssl.h
sha512_digest_openssl.cpp
sha512_digest_openssl.h
)

View File

@ -0,0 +1,187 @@
/*
* Created by victoria on 2021-05-13.
*/
#include "aes_openssl.h"
#include <memory>
extern "C" {
#include <openssl/evp.h>
#include <openssl/opensslv.h>
}
using namespace Signal::Crypto;
class EVPCipherCtxWrapper {
public:
EVPCipherCtxWrapper() {
#if OPENSSL_VERSION_NUMBER >= 0x1010000fL
ctx = EVP_CIPHER_CTX_new();
#else
ctx = new EVP_CIPHER_CTX;
EVP_CIPHER_CTX_init(ctx);
#endif
}
~EVPCipherCtxWrapper() {
if (good()) {
#if OPENSSL_VERSION_NUMBER >= 0x1010000fL
EVP_CIPHER_CTX_free(ctx);
#else
EVP_CIPHER_CTX_cleanup(ctx);
delete ctx;
#endif
}
}
EVPCipherCtxWrapper(const EVPCipherCtxWrapper &) = delete;
EVPCipherCtxWrapper(EVPCipherCtxWrapper &&) = delete;
EVPCipherCtxWrapper &operator=(const EVPCipherCtxWrapper &) = delete;
[[nodiscard]] bool good() const { return ctx != nullptr; }
[[nodiscard]] EVP_CIPHER_CTX *operator*() const { return ctx; }
private:
EVP_CIPHER_CTX *ctx{nullptr};
};
static const EVP_CIPHER *aes_cipher(int cipher, size_t key_len) {
if (cipher == SG_CIPHER_AES_CBC_PKCS5) {
if (key_len == 16) {
return EVP_aes_128_cbc();
} else if (key_len == 24) {
return EVP_aes_192_cbc();
} else if (key_len == 32) {
return EVP_aes_256_cbc();
}
} else if (cipher == SG_CIPHER_AES_CTR_NOPADDING) {
if (key_len == 16) {
return EVP_aes_128_ctr();
} else if (key_len == 24) {
return EVP_aes_192_ctr();
} else if (key_len == 32) {
return EVP_aes_256_ctr();
}
}
return nullptr;
}
int Aes::encrypt(signal_buffer **output, int cipher, const uint8_t *key, size_t key_len, const uint8_t *iv,
size_t iv_len, const uint8_t *plaintext, size_t plaintext_len, void *) {
const EVP_CIPHER *evp_cipher = aes_cipher(cipher, key_len);
if (!evp_cipher) {
fprintf(stderr, "invalid AES mode or key size: %zu\n", key_len);
return SG_ERR_UNKNOWN;
}
if (iv_len != 16) {
fprintf(stderr, "invalid AES IV size: %zu\n", iv_len);
return SG_ERR_UNKNOWN;
}
if (plaintext_len > INT_MAX - EVP_CIPHER_block_size(evp_cipher)) {
fprintf(stderr, "invalid plaintext length: %zu\n", plaintext_len);
return SG_ERR_UNKNOWN;
}
EVPCipherCtxWrapper ctx{};
if (!ctx.good()) {
fprintf(stderr, "could not create context\n");
return SG_ERR_UNKNOWN;
}
auto result = EVP_EncryptInit_ex(*ctx, evp_cipher, nullptr, key, iv);
if (!result) {
fprintf(stderr, "cannot initialize cipher\n");
return SG_ERR_UNKNOWN;
}
if (cipher == SG_CIPHER_AES_CTR_NOPADDING) {
result = EVP_CIPHER_CTX_set_padding(*ctx, 0);
if (!result) {
fprintf(stderr, "cannot set padding\n");
return SG_ERR_UNKNOWN;
}
}
auto out_buf = std::make_unique<uint8_t>(plaintext_len + EVP_CIPHER_block_size(evp_cipher));
int out_len = 0;
result = EVP_EncryptUpdate(*ctx, out_buf.get(), &out_len, plaintext,
plaintext_len);
if (!result) {
fprintf(stderr, "cannot encrypt plaintext\n");
return SG_ERR_UNKNOWN;
}
int final_len = 0;
result = EVP_EncryptFinal_ex(*ctx, out_buf.get() + out_len, &final_len);
if (!result) {
fprintf(stderr, "cannot finish encrypting plaintext\n");
return SG_ERR_UNKNOWN;
}
*output = signal_buffer_create(out_buf.get(), out_len + final_len);
return result;
}
int Aes::decrypt(signal_buffer **output, int cipher, const uint8_t *key, size_t key_len, const uint8_t *iv,
size_t iv_len, const uint8_t *ciphertext, size_t ciphertext_len, void *) {
const EVP_CIPHER *evp_cipher = aes_cipher(cipher, key_len);
if (!evp_cipher) {
fprintf(stderr, "invalid AES mode or key size: %zu\n", key_len);
return SG_ERR_INVAL;
}
if (iv_len != 16) {
fprintf(stderr, "invalid AES IV size: %zu\n", iv_len);
return SG_ERR_INVAL;
}
if (ciphertext_len > INT_MAX - EVP_CIPHER_block_size(evp_cipher)) {
fprintf(stderr, "invalid ciphertext length: %zu\n", ciphertext_len);
return SG_ERR_UNKNOWN;
}
EVPCipherCtxWrapper ctx{};
if (!ctx.good()) {
fprintf(stderr, "could not create context\n");
return SG_ERR_UNKNOWN;
}
auto result = EVP_DecryptInit_ex(*ctx, evp_cipher, nullptr, key, iv);
if (!result) {
fprintf(stderr, "cannot initialize cipher\n");
return SG_ERR_UNKNOWN;
}
if (cipher == SG_CIPHER_AES_CTR_NOPADDING) {
result = EVP_CIPHER_CTX_set_padding(*ctx, 0);
if (!result) {
fprintf(stderr, "cannot set padding\n");
return SG_ERR_UNKNOWN;
}
}
auto out_buf = std::make_unique<uint8_t>(ciphertext_len + EVP_CIPHER_block_size(evp_cipher));
int out_len = 0;
result = EVP_DecryptUpdate(*ctx, out_buf.get(), &out_len, ciphertext, ciphertext_len);
if (!result) {
fprintf(stderr, "cannot decrypt ciphertext\n");
return SG_ERR_UNKNOWN;
}
int final_len = 0;
result = EVP_DecryptFinal_ex(*ctx, out_buf.get() + out_len, &final_len);
if (!result) {
fprintf(stderr, "cannot finish decrypting ciphertext\n");
return SG_ERR_UNKNOWN;
}
*output = signal_buffer_create(out_buf.get(), out_len + final_len);
return result;
}

View File

@ -0,0 +1,17 @@
/*
* Created by victoria on 2021-05-13.
*/
#pragma once
#include <signal/signal_protocol.h>
namespace Signal::Crypto::Aes {
int encrypt(signal_buffer **output, int cipher, const uint8_t *key, size_t key_len, const uint8_t *iv,
size_t iv_len, const uint8_t *plaintext, size_t plaintext_len, void *user_data);
int decrypt(signal_buffer **output, int cipher, const uint8_t *key, size_t key_len, const uint8_t *iv,
size_t iv_len, const uint8_t *ciphertext, size_t ciphertext_len, void *user_data);
} // namespace Signal::Crypto::Aes

View File

@ -0,0 +1,40 @@
/*
* Created by victoria on 2021-05-13.
*/
#include "crypto.h"
extern "C" {
#include <openssl/rand.h>
}
#include "aes_openssl.h"
#include "hmac_sha256_openssl.h"
#include "sha512_digest_openssl.h"
int random_func(uint8_t *data, size_t len, void *) {
if (RAND_bytes(data, len)) {
return 0;
} else {
return SG_ERR_UNKNOWN;
}
}
signal_crypto_provider Signal::Crypto::createProvider() {
signal_crypto_provider result{};
result.random_func = random_func;
result.hmac_sha256_init_func = HmacSha256::init;
result.hmac_sha256_update_func = HmacSha256::update;
result.hmac_sha256_final_func = HmacSha256::final;
result.hmac_sha256_cleanup_func = HmacSha256::cleanup;
result.sha512_digest_init_func = Sha512::init;
result.sha512_digest_update_func = Sha512::update;
result.sha512_digest_final_func = Sha512::final;
result.sha512_digest_cleanup_func = Sha512::cleanup;
result.encrypt_func = Aes::encrypt;
result.decrypt_func = Aes::decrypt;
result.user_data = nullptr;
return result;
}

View File

@ -0,0 +1,13 @@
/*
* Created by victoria on 2021-05-13.
*/
#pragma once
#include <signal/signal_protocol.h>
namespace Signal::Crypto {
signal_crypto_provider createProvider();
}

View File

@ -0,0 +1,71 @@
/*
* Created by victoria on 2021-05-13.
*/
#include "hmac_sha256_openssl.h"
extern "C" {
#include <openssl/evp.h>
#include <openssl/hmac.h>
#include <openssl/sha.h>
}
using namespace Signal::Crypto;
int HmacSha256::init(void **hmac_context, const uint8_t *key, size_t key_len, void *) {
#if OPENSSL_VERSION_NUMBER >= 0x1010000fL
HMAC_CTX *ctx = HMAC_CTX_new();
if (!ctx) {
return SG_ERR_NOMEM;
}
#else
auto ctx = new HMAC_CTX;
HMAC_CTX_init(ctx);
#endif
*hmac_context = ctx;
if (HMAC_Init_ex(ctx, key, key_len, EVP_sha256(), nullptr) != 1) {
return SG_ERR_UNKNOWN;
}
return SG_SUCCESS;
}
int HmacSha256::update(void *hmac_context, const uint8_t *data, size_t data_len, void *) {
auto ctx = static_cast<HMAC_CTX *>(hmac_context);
int result = HMAC_Update(ctx, data, data_len);
return (result == 1) ? SG_SUCCESS : SG_ERR_UNKNOWN;
}
int HmacSha256::final(void *hmac_context, signal_buffer **output, void *) {
auto ctx = static_cast<HMAC_CTX *>(hmac_context);
unsigned char md[EVP_MAX_MD_SIZE];
unsigned int len = 0;
if (HMAC_Final(ctx, md, &len) != 1) {
return SG_ERR_UNKNOWN;
}
signal_buffer *output_buffer = signal_buffer_create(md, len);
if (!output_buffer) {
return SG_ERR_NOMEM;
}
*output = output_buffer;
return SG_SUCCESS;
}
void HmacSha256::cleanup(void *hmac_context, void *) {
if (hmac_context) {
auto ctx = static_cast<HMAC_CTX *>(hmac_context);
#if OPENSSL_VERSION_NUMBER >= 0x1010000fL
HMAC_CTX_free(ctx);
#else
HMAC_CTX_cleanup(ctx);
delete ctx;
#endif
}
}

View File

@ -0,0 +1,16 @@
/*
* Created by victoria on 2021-05-13.
*/
#pragma once
#include <signal/signal_protocol.h>
namespace Signal::Crypto::HmacSha256 {
int init(void **hmac_context, const uint8_t *key, size_t key_len, void *);
int update(void *hmac_context, const uint8_t *data, size_t data_len, void *);
int final(void *hmac_context, signal_buffer **output, void *);
void cleanup(void *hmac_context, void *);
} // namespace Signal::Crypto::HmacSha256

View File

@ -0,0 +1,67 @@
/*
* Created by victoria on 2021-05-13.
*/
#include "sha512_digest_openssl.h"
extern "C" {
#include <openssl/evp.h>
#include <openssl/rand.h>
#include <openssl/sha.h>
}
using namespace Signal::Crypto;
int Sha512::init(void **digest_context, void *) {
auto ctx = EVP_MD_CTX_create();
if (!ctx) {
return SG_ERR_NOMEM;
}
auto result = EVP_DigestInit_ex(ctx, EVP_sha512(), nullptr);
if (result == 1) {
*digest_context = ctx;
return SG_SUCCESS;
}
EVP_MD_CTX_destroy(ctx);
return SG_ERR_UNKNOWN;
}
int Sha512::update(void *digest_context, const uint8_t *data, size_t data_len, void *) {
auto ctx = static_cast<EVP_MD_CTX *>(digest_context);
auto result = EVP_DigestUpdate(ctx, data, data_len);
return (result == 1) ? SG_SUCCESS : SG_ERR_UNKNOWN;
}
int Sha512::final(void *digest_context, signal_buffer **output, void *) {
auto ctx = static_cast<EVP_MD_CTX *>(digest_context);
unsigned char md[EVP_MAX_MD_SIZE];
unsigned int len = 0;
auto result = EVP_DigestFinal_ex(ctx, md, &len);
if (result != 1) {
return SG_ERR_UNKNOWN;
}
result = EVP_DigestInit_ex(ctx, EVP_sha512(), nullptr);
if (result != 1) {
return SG_ERR_UNKNOWN;
}
signal_buffer *output_buffer = signal_buffer_create(md, len);
if (!output_buffer) {
return SG_ERR_NOMEM;
}
*output = output_buffer;
return SG_SUCCESS;
}
void Sha512::cleanup(void *digest_context, void *) {
auto ctx = static_cast<EVP_MD_CTX *>(digest_context);
EVP_MD_CTX_destroy(ctx);
}

View File

@ -0,0 +1,16 @@
/*
* Created by victoria on 2021-05-13.
*/
#pragma once
#include <signal/signal_protocol.h>
namespace Signal::Crypto::Sha512 {
int init(void **digest_context, void *);
int update(void *digest_context, const uint8_t *data, size_t data_len, void *);
int final(void *digest_context, signal_buffer **output, void *);
void cleanup(void *digest_context, void *);
} // namespace Signal::Crypto::Sha512

View File

@ -0,0 +1,14 @@
target_sources(squawk PRIVATE
identity_key_store.cpp
identity_key_store.h
pre_key_store.cpp
pre_key_store.h
sender_key_store.cpp
sender_key_store.h
session_store.cpp
session_store.h
signed_pre_key_store.cpp
signed_pre_key_store.h
store_context.cpp
store_context.h
)

View File

@ -0,0 +1,47 @@
/*
* Created by victoria on 2021-05-13.
*/
#include "identity_key_store.h"
void Signal::Store::IdentityKeyStore::boundToContext(
signal_protocol_store_context *ctx) {
signal_protocol_identity_key_store store{};
store.user_data = nullptr;
store.destroy_func = nullptr;
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);
};
store.get_local_registration_id = [](void *ptr, uint32_t *registrationId) {
return static_cast<IdentityKeyStore *>(ptr)->getLocalRegistrationId(registrationId);
};
store.is_trusted_identity = [](const signal_protocol_address *address, uint8_t *key_data, size_t key_len,
void *ptr) {
return static_cast<IdentityKeyStore *>(ptr)->isTrustedIdentity(address, key_data, key_len);
};
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;
}

View File

@ -0,0 +1,21 @@
/*
* Created by victoria on 2021-05-13.
*/
#pragma once
#include <signal/signal_protocol.h>
namespace Signal::Store {
class IdentityKeyStore {
public:
static void boundToContext(signal_protocol_store_context *ctx);
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);
};
} // namespace Signal::Store

View File

@ -0,0 +1,43 @@
/*
* Created by victoria on 2021-05-13.
*/
#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);
}
int Signal::Store::PreKeyStore::containsPreKey(uint32_t pre_key_id) {
return 0;
}
int Signal::Store::PreKeyStore::loadPreKey(signal_buffer **record, uint32_t pre_key_id) {
return 0;
}
int Signal::Store::PreKeyStore::storePreKey(uint32_t pre_key_id, uint8_t *record, size_t record_len) {
return 0;
}
int Signal::Store::PreKeyStore::removePreKey(uint32_t pre_key_id) { return 0; }

View File

@ -0,0 +1,21 @@
/*
* Created by victoria on 2021-05-13.
*/
#pragma once
#include <signal/signal_protocol.h>
namespace Signal::Store {
class PreKeyStore {
public:
static void boundToContext(signal_protocol_store_context *ctx);
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);
};
} // namespace Signal::Store

View File

@ -0,0 +1,36 @@
/*
* Created by victoria on 2021-05-13.
*/
#include "sender_key_store.h"
void Signal::Store::SenderKeyStore::boundToContext(
signal_protocol_store_context *ctx) {
signal_protocol_sender_key_store store{};
store.user_data = nullptr;
store.destroy_func = nullptr;
store.load_sender_key = [](signal_buffer **record, signal_buffer **user_record,
const signal_protocol_sender_key_name *sender_key_name, void *ptr) {
return static_cast<SenderKeyStore *>(ptr)->loadSenderKey(record, user_record, sender_key_name);
};
store.store_sender_key = [](const signal_protocol_sender_key_name *sender_key_name, uint8_t *record,
size_t record_len, uint8_t *user_record, size_t user_record_len, void *ptr) {
return static_cast<SenderKeyStore *>(ptr)->storeSenderKey(sender_key_name, record, record_len, user_record,
user_record_len);
};
signal_protocol_store_context_set_sender_key_store(ctx, &store);
}
int Signal::Store::SenderKeyStore::loadSenderKey(signal_buffer **record, signal_buffer **user_record,
const signal_protocol_sender_key_name *sender_key_name) {
return 0;
}
int Signal::Store::SenderKeyStore::storeSenderKey(const signal_protocol_sender_key_name *sender_key_name,
uint8_t *record, size_t record_len, uint8_t *user_record,
size_t user_record_len) {
return 0;
}

View File

@ -0,0 +1,21 @@
/*
* Created by victoria on 2021-05-13.
*/
#pragma once
#include <signal/signal_protocol.h>
namespace Signal::Store {
class SenderKeyStore {
public:
static void boundToContext(signal_protocol_store_context *ctx);
int storeSenderKey(const signal_protocol_sender_key_name *sender_key_name, uint8_t *record, size_t record_len,
uint8_t *user_record, size_t user_record_len);
int loadSenderKey(signal_buffer **record, signal_buffer **user_record,
const signal_protocol_sender_key_name *sender_key_name);
};
} // namespace Signal::Store

View File

@ -0,0 +1,63 @@
/*
* Created by victoria on 2021-05-13.
*/
#include "session_store.h"
void Signal::Store::SessionStore::boundToContext(
signal_protocol_store_context *ctx) {
signal_protocol_session_store store{};
store.user_data = nullptr;
store.destroy_func = nullptr;
store.load_session_func = [](signal_buffer **record, signal_buffer **user_record,
const signal_protocol_address *address, void *ptr) {
return static_cast<SessionStore *>(ptr)->loadSession(record, user_record, address);
};
store.get_sub_device_sessions_func = [](signal_int_list **sessions, const char *name, size_t name_len, void *ptr) {
return static_cast<SessionStore *>(ptr)->getSubDeviceSessions(sessions, name, name_len);
};
store.store_session_func = [](const signal_protocol_address *address, uint8_t *record, size_t record_len,
uint8_t *user_record, size_t user_record_len, void *ptr) {
return static_cast<SessionStore *>(ptr)->storeSession(address, record, record_len, user_record,
user_record_len);
};
store.contains_session_func = [](const signal_protocol_address *address, void *ptr) {
return static_cast<SessionStore *>(ptr)->containsSession(address);
};
store.delete_session_func = [](const signal_protocol_address *address, void *ptr) {
return static_cast<SessionStore *>(ptr)->deleteSession(address);
};
store.delete_all_sessions_func = [](const char *name, size_t name_len, void *ptr) {
return static_cast<SessionStore *>(ptr)->deleteAllSessions(name, name_len);
};
signal_protocol_store_context_set_session_store(ctx, &store);
}
int Signal::Store::SessionStore::loadSession(signal_buffer **record, signal_buffer **user_record,
const signal_protocol_address *address) {
return 0;
}
int Signal::Store::SessionStore::getSubDeviceSessions(signal_int_list **sessions, const char *name, size_t name_len) {
return 0;
}
int Signal::Store::SessionStore::storeSession(const signal_protocol_address *address, uint8_t *record,
size_t record_len, uint8_t *user_record, size_t user_record_len) {
return 0;
}
int Signal::Store::SessionStore::containsSession(const signal_protocol_address *address) {
return 0;
}
int Signal::Store::SessionStore::deleteSession(const signal_protocol_address *address) {
return 0;
}
int Signal::Store::SessionStore::deleteAllSessions(const char *name, size_t name_len) {
return 0;
}

View File

@ -0,0 +1,24 @@
/*
* Created by victoria on 2021-05-13.
*/
#pragma once
#include <signal/signal_protocol.h>
namespace Signal::Store {
class SessionStore {
public:
static void boundToContext(signal_protocol_store_context *ctx);
int loadSession(signal_buffer **record, signal_buffer **user_record, const signal_protocol_address *address);
int getSubDeviceSessions(signal_int_list **sessions, const char *name, size_t name_len);
int storeSession(const signal_protocol_address *address, uint8_t *record, size_t record_len,
uint8_t *user_record, size_t user_record_len);
int containsSession(const signal_protocol_address *address);
int deleteSession(const signal_protocol_address *address);
int deleteAllSessions(const char *name, size_t name_len);
};
} // namespace Signal::Store

View File

@ -0,0 +1,48 @@
/*
* Created by victoria on 2021-05-13.
*/
#include "signed_pre_key_store.h"
void Signal::Store::SignedPreKeyStore::boundToContext(
signal_protocol_store_context *ctx) {
signal_protocol_signed_pre_key_store store{};
store.user_data = nullptr;
store.destroy_func = nullptr;
store.load_signed_pre_key = [](signal_buffer **record, uint32_t signed_pre_key_id, void *ptr) {
return static_cast<SignedPreKeyStore *>(ptr)->loadSignedPreKey(
record, signed_pre_key_id);
};
store.store_signed_pre_key = [](uint32_t signed_pre_key_id, uint8_t *record, size_t record_len, void *ptr) {
return static_cast<SignedPreKeyStore *>(ptr)->storeSignedPreKey(
signed_pre_key_id, record, record_len);
};
store.contains_signed_pre_key = [](uint32_t signed_pre_key_id, void *ptr) {
return static_cast<SignedPreKeyStore *>(ptr)->containsSignedPreKey(
signed_pre_key_id);
};
store.remove_signed_pre_key = [](uint32_t signed_pre_key_id, void *ptr) {
return static_cast<SignedPreKeyStore *>(ptr)->removeSignedPreKey(
signed_pre_key_id);
};
signal_protocol_store_context_set_signed_pre_key_store(ctx, &store);
}
int Signal::Store::SignedPreKeyStore::loadSignedPreKey(signal_buffer **record, uint32_t signed_pre_key_id) {
return 0;
}
int Signal::Store::SignedPreKeyStore::storeSignedPreKey(uint32_t signed_pre_key_id, uint8_t *record, size_t record_len) {
return 0;
}
int Signal::Store::SignedPreKeyStore::containsSignedPreKey(uint32_t signed_pre_key_id) {
return 0;
}
int Signal::Store::SignedPreKeyStore::removeSignedPreKey(uint32_t signed_pre_key_id) {
return 0;
}

View File

@ -0,0 +1,20 @@
/*
* Created by victoria on 2021-05-13.
*/
#pragma once
#include <signal/signal_protocol.h>
namespace Signal::Store {
class SignedPreKeyStore {
public:
static void boundToContext(signal_protocol_store_context *ctx);
int loadSignedPreKey(signal_buffer **record, uint32_t signed_pre_key_id);
int storeSignedPreKey(uint32_t signed_pre_key_id, uint8_t *record, size_t record_len);
int containsSignedPreKey(uint32_t signed_pre_key_id);
int removeSignedPreKey(uint32_t signed_pre_key_id);
};
} // namespace Signal::Store

View File

@ -0,0 +1,13 @@
/*
* Created by victoria on 2021-05-13.
*/
#include "store_context.h"
Signal::Store::Context::Context(signal_context *global) {
signal_protocol_store_context_create(&ctx, global);
}
Signal::Store::Context::~Context() {
signal_protocol_store_context_destroy(ctx);
}

View File

@ -0,0 +1,24 @@
/*
* Created by victoria on 2021-05-13.
*/
#pragma once
#include <signal/signal_protocol.h>
namespace Signal::Store {
class Context {
public:
explicit Context(signal_context *global);
~Context();
Context(const Context &) = delete;
Context(Context &&) = delete;
Context &operator=(const Context &) = delete;
private:
signal_protocol_store_context *ctx{nullptr};
};
} // namespace Signal::Store