From 2654e386657fcd5d6b1e568587598c60c38e8741 Mon Sep 17 00:00:00 2001 From: vae Date: Thu, 13 May 2021 17:50:29 +0300 Subject: [PATCH] feat(omemo): add signal protocol wrappers --- qomemo/CMakeLists.txt | 5 +- qomemo/signal.cpp | 5 - qomemo/signal.h | 20 -- qomemo/signal/CMakeLists.txt | 7 + qomemo/signal/context.cpp | 9 + qomemo/signal/context.h | 23 +++ qomemo/signal/crypto/CMakeLists.txt | 10 + qomemo/signal/crypto/aes_openssl.cpp | 187 ++++++++++++++++++ qomemo/signal/crypto/aes_openssl.h | 17 ++ qomemo/signal/crypto/crypto.cpp | 40 ++++ qomemo/signal/crypto/crypto.h | 13 ++ qomemo/signal/crypto/hmac_sha256_openssl.cpp | 71 +++++++ qomemo/signal/crypto/hmac_sha256_openssl.h | 16 ++ .../signal/crypto/sha512_digest_openssl.cpp | 67 +++++++ qomemo/signal/crypto/sha512_digest_openssl.h | 16 ++ qomemo/signal/stores/CMakeLists.txt | 14 ++ qomemo/signal/stores/identity_key_store.cpp | 47 +++++ qomemo/signal/stores/identity_key_store.h | 21 ++ qomemo/signal/stores/pre_key_store.cpp | 43 ++++ qomemo/signal/stores/pre_key_store.h | 21 ++ qomemo/signal/stores/sender_key_store.cpp | 36 ++++ qomemo/signal/stores/sender_key_store.h | 21 ++ qomemo/signal/stores/session_store.cpp | 63 ++++++ qomemo/signal/stores/session_store.h | 24 +++ qomemo/signal/stores/signed_pre_key_store.cpp | 48 +++++ qomemo/signal/stores/signed_pre_key_store.h | 20 ++ qomemo/signal/stores/store_context.cpp | 13 ++ qomemo/signal/stores/store_context.h | 24 +++ 28 files changed, 874 insertions(+), 27 deletions(-) delete mode 100644 qomemo/signal.cpp delete mode 100644 qomemo/signal.h create mode 100644 qomemo/signal/CMakeLists.txt create mode 100644 qomemo/signal/context.cpp create mode 100644 qomemo/signal/context.h create mode 100644 qomemo/signal/crypto/CMakeLists.txt create mode 100644 qomemo/signal/crypto/aes_openssl.cpp create mode 100644 qomemo/signal/crypto/aes_openssl.h create mode 100644 qomemo/signal/crypto/crypto.cpp create mode 100644 qomemo/signal/crypto/crypto.h create mode 100644 qomemo/signal/crypto/hmac_sha256_openssl.cpp create mode 100644 qomemo/signal/crypto/hmac_sha256_openssl.h create mode 100644 qomemo/signal/crypto/sha512_digest_openssl.cpp create mode 100644 qomemo/signal/crypto/sha512_digest_openssl.h create mode 100644 qomemo/signal/stores/CMakeLists.txt create mode 100644 qomemo/signal/stores/identity_key_store.cpp create mode 100644 qomemo/signal/stores/identity_key_store.h create mode 100644 qomemo/signal/stores/pre_key_store.cpp create mode 100644 qomemo/signal/stores/pre_key_store.h create mode 100644 qomemo/signal/stores/sender_key_store.cpp create mode 100644 qomemo/signal/stores/sender_key_store.h create mode 100644 qomemo/signal/stores/session_store.cpp create mode 100644 qomemo/signal/stores/session_store.h create mode 100644 qomemo/signal/stores/signed_pre_key_store.cpp create mode 100644 qomemo/signal/stores/signed_pre_key_store.h create mode 100644 qomemo/signal/stores/store_context.cpp create mode 100644 qomemo/signal/stores/store_context.h diff --git a/qomemo/CMakeLists.txt b/qomemo/CMakeLists.txt index 95fca3f..7391404 100644 --- a/qomemo/CMakeLists.txt +++ b/qomemo/CMakeLists.txt @@ -1,14 +1,14 @@ target_sources(squawk PRIVATE bundle.cpp bundle.h + database.cpp + database.h device.cpp device.h device_key_storage.cpp device_key_storage.h device_service.cpp device_service.h - signal.h - signal.cpp qomemo.cpp qomemo.h sce.cpp @@ -19,4 +19,5 @@ target_sources(squawk PRIVATE qxmpp_omemo_manager.h ) +add_subdirectory(signal) add_subdirectory(variant) diff --git a/qomemo/signal.cpp b/qomemo/signal.cpp deleted file mode 100644 index 0e5257b..0000000 --- a/qomemo/signal.cpp +++ /dev/null @@ -1,5 +0,0 @@ -/* - * Created by victoria on 2021-05-11. - */ - -#include "signal.h" diff --git a/qomemo/signal.h b/qomemo/signal.h deleted file mode 100644 index 4aa5701..0000000 --- a/qomemo/signal.h +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Created by victoria on 2021-05-11. - */ - -#pragma once - -#include - -namespace Signal -{ - -class Context {}; -class RatchetIdentityPair {}; -class SessionSignedPreKey {}; -class ProtocolKeyHelper {}; -class ProtocolStoreContext {}; -class SessionBuilder {}; -class SessionCipher {}; - -} diff --git a/qomemo/signal/CMakeLists.txt b/qomemo/signal/CMakeLists.txt new file mode 100644 index 0000000..60cfdd8 --- /dev/null +++ b/qomemo/signal/CMakeLists.txt @@ -0,0 +1,7 @@ +target_sources(squawk PRIVATE + context.cpp + context.h + ) + +add_subdirectory(crypto) +add_subdirectory(stores) \ No newline at end of file diff --git a/qomemo/signal/context.cpp b/qomemo/signal/context.cpp new file mode 100644 index 0000000..bc2322e --- /dev/null +++ b/qomemo/signal/context.cpp @@ -0,0 +1,9 @@ +/* + * Created by victoria on 2021-05-13. + */ + +#include "context.h" + +Signal::Context::Context() {} + +Signal::Context::~Context() {} diff --git a/qomemo/signal/context.h b/qomemo/signal/context.h new file mode 100644 index 0000000..c398105 --- /dev/null +++ b/qomemo/signal/context.h @@ -0,0 +1,23 @@ +/* + * Created by victoria on 2021-05-13. + */ + +#pragma once + +#include + +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 diff --git a/qomemo/signal/crypto/CMakeLists.txt b/qomemo/signal/crypto/CMakeLists.txt new file mode 100644 index 0000000..6359510 --- /dev/null +++ b/qomemo/signal/crypto/CMakeLists.txt @@ -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 + ) diff --git a/qomemo/signal/crypto/aes_openssl.cpp b/qomemo/signal/crypto/aes_openssl.cpp new file mode 100644 index 0000000..17f2df8 --- /dev/null +++ b/qomemo/signal/crypto/aes_openssl.cpp @@ -0,0 +1,187 @@ +/* + * Created by victoria on 2021-05-13. + */ + +#include "aes_openssl.h" +#include + +extern "C" { +#include +#include +} + +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(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(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; +} \ No newline at end of file diff --git a/qomemo/signal/crypto/aes_openssl.h b/qomemo/signal/crypto/aes_openssl.h new file mode 100644 index 0000000..63f4635 --- /dev/null +++ b/qomemo/signal/crypto/aes_openssl.h @@ -0,0 +1,17 @@ +/* + * Created by victoria on 2021-05-13. + */ + +#pragma once + +#include + +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 diff --git a/qomemo/signal/crypto/crypto.cpp b/qomemo/signal/crypto/crypto.cpp new file mode 100644 index 0000000..d6a6058 --- /dev/null +++ b/qomemo/signal/crypto/crypto.cpp @@ -0,0 +1,40 @@ +/* + * Created by victoria on 2021-05-13. + */ + +#include "crypto.h" + +extern "C" { +#include +} + +#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; +} diff --git a/qomemo/signal/crypto/crypto.h b/qomemo/signal/crypto/crypto.h new file mode 100644 index 0000000..2fbff31 --- /dev/null +++ b/qomemo/signal/crypto/crypto.h @@ -0,0 +1,13 @@ +/* + * Created by victoria on 2021-05-13. + */ + +#pragma once + +#include + +namespace Signal::Crypto { + + signal_crypto_provider createProvider(); + +} diff --git a/qomemo/signal/crypto/hmac_sha256_openssl.cpp b/qomemo/signal/crypto/hmac_sha256_openssl.cpp new file mode 100644 index 0000000..2a8aba5 --- /dev/null +++ b/qomemo/signal/crypto/hmac_sha256_openssl.cpp @@ -0,0 +1,71 @@ +/* + * Created by victoria on 2021-05-13. + */ + +#include "hmac_sha256_openssl.h" + +extern "C" { +#include +#include +#include +} + +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_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_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_context); +#if OPENSSL_VERSION_NUMBER >= 0x1010000fL + HMAC_CTX_free(ctx); +#else + HMAC_CTX_cleanup(ctx); + delete ctx; +#endif + } +} \ No newline at end of file diff --git a/qomemo/signal/crypto/hmac_sha256_openssl.h b/qomemo/signal/crypto/hmac_sha256_openssl.h new file mode 100644 index 0000000..03fe8e0 --- /dev/null +++ b/qomemo/signal/crypto/hmac_sha256_openssl.h @@ -0,0 +1,16 @@ +/* + * Created by victoria on 2021-05-13. + */ + +#pragma once + +#include + +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 diff --git a/qomemo/signal/crypto/sha512_digest_openssl.cpp b/qomemo/signal/crypto/sha512_digest_openssl.cpp new file mode 100644 index 0000000..360f11e --- /dev/null +++ b/qomemo/signal/crypto/sha512_digest_openssl.cpp @@ -0,0 +1,67 @@ +/* + * Created by victoria on 2021-05-13. + */ + +#include "sha512_digest_openssl.h" + +extern "C" { +#include +#include +#include +} + +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(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(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(digest_context); + EVP_MD_CTX_destroy(ctx); +} \ No newline at end of file diff --git a/qomemo/signal/crypto/sha512_digest_openssl.h b/qomemo/signal/crypto/sha512_digest_openssl.h new file mode 100644 index 0000000..8b263a2 --- /dev/null +++ b/qomemo/signal/crypto/sha512_digest_openssl.h @@ -0,0 +1,16 @@ +/* + * Created by victoria on 2021-05-13. + */ + +#pragma once + +#include + +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 diff --git a/qomemo/signal/stores/CMakeLists.txt b/qomemo/signal/stores/CMakeLists.txt new file mode 100644 index 0000000..971b87b --- /dev/null +++ b/qomemo/signal/stores/CMakeLists.txt @@ -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 + ) \ No newline at end of file diff --git a/qomemo/signal/stores/identity_key_store.cpp b/qomemo/signal/stores/identity_key_store.cpp new file mode 100644 index 0000000..a8b28df --- /dev/null +++ b/qomemo/signal/stores/identity_key_store.cpp @@ -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(ptr)->getIdentityKeyPair(public_data, private_data); + }; + store.get_local_registration_id = [](void *ptr, uint32_t *registrationId) { + return static_cast(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(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(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; +} diff --git a/qomemo/signal/stores/identity_key_store.h b/qomemo/signal/stores/identity_key_store.h new file mode 100644 index 0000000..4179430 --- /dev/null +++ b/qomemo/signal/stores/identity_key_store.h @@ -0,0 +1,21 @@ +/* + * Created by victoria on 2021-05-13. + */ + +#pragma once + +#include + +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 diff --git a/qomemo/signal/stores/pre_key_store.cpp b/qomemo/signal/stores/pre_key_store.cpp new file mode 100644 index 0000000..fe4cd60 --- /dev/null +++ b/qomemo/signal/stores/pre_key_store.cpp @@ -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(ptr)->containsPreKey(id); + }; + store.load_pre_key = [](signal_buffer **record, uint32_t id, void *ptr) { + return static_cast(ptr)->loadPreKey(record, id); + }; + store.remove_pre_key = [](uint32_t id, void *ptr) { + return static_cast(ptr)->removePreKey(id); + }; + store.store_pre_key = [](uint32_t id, uint8_t *record, size_t size, + void *ptr) { + return static_cast(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; } diff --git a/qomemo/signal/stores/pre_key_store.h b/qomemo/signal/stores/pre_key_store.h new file mode 100644 index 0000000..eb70786 --- /dev/null +++ b/qomemo/signal/stores/pre_key_store.h @@ -0,0 +1,21 @@ +/* + * Created by victoria on 2021-05-13. + */ + +#pragma once + +#include + +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 diff --git a/qomemo/signal/stores/sender_key_store.cpp b/qomemo/signal/stores/sender_key_store.cpp new file mode 100644 index 0000000..a1cb687 --- /dev/null +++ b/qomemo/signal/stores/sender_key_store.cpp @@ -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(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(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; +} diff --git a/qomemo/signal/stores/sender_key_store.h b/qomemo/signal/stores/sender_key_store.h new file mode 100644 index 0000000..904377e --- /dev/null +++ b/qomemo/signal/stores/sender_key_store.h @@ -0,0 +1,21 @@ +/* + * Created by victoria on 2021-05-13. + */ + +#pragma once + +#include + +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 diff --git a/qomemo/signal/stores/session_store.cpp b/qomemo/signal/stores/session_store.cpp new file mode 100644 index 0000000..311b3e6 --- /dev/null +++ b/qomemo/signal/stores/session_store.cpp @@ -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(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(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(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(ptr)->containsSession(address); + }; + store.delete_session_func = [](const signal_protocol_address *address, void *ptr) { + return static_cast(ptr)->deleteSession(address); + }; + store.delete_all_sessions_func = [](const char *name, size_t name_len, void *ptr) { + return static_cast(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; +} diff --git a/qomemo/signal/stores/session_store.h b/qomemo/signal/stores/session_store.h new file mode 100644 index 0000000..848e5b8 --- /dev/null +++ b/qomemo/signal/stores/session_store.h @@ -0,0 +1,24 @@ +/* + * Created by victoria on 2021-05-13. + */ + +#pragma once + +#include + +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 diff --git a/qomemo/signal/stores/signed_pre_key_store.cpp b/qomemo/signal/stores/signed_pre_key_store.cpp new file mode 100644 index 0000000..0156894 --- /dev/null +++ b/qomemo/signal/stores/signed_pre_key_store.cpp @@ -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(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(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(ptr)->containsSignedPreKey( + signed_pre_key_id); + }; + store.remove_signed_pre_key = [](uint32_t signed_pre_key_id, void *ptr) { + return static_cast(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; +} diff --git a/qomemo/signal/stores/signed_pre_key_store.h b/qomemo/signal/stores/signed_pre_key_store.h new file mode 100644 index 0000000..3f58851 --- /dev/null +++ b/qomemo/signal/stores/signed_pre_key_store.h @@ -0,0 +1,20 @@ +/* + * Created by victoria on 2021-05-13. + */ + +#pragma once + +#include + +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 diff --git a/qomemo/signal/stores/store_context.cpp b/qomemo/signal/stores/store_context.cpp new file mode 100644 index 0000000..dd5bb5e --- /dev/null +++ b/qomemo/signal/stores/store_context.cpp @@ -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); +} diff --git a/qomemo/signal/stores/store_context.h b/qomemo/signal/stores/store_context.h new file mode 100644 index 0000000..204d9b9 --- /dev/null +++ b/qomemo/signal/stores/store_context.h @@ -0,0 +1,24 @@ +/* + * Created by victoria on 2021-05-13. + */ + +#pragma once + +#include + +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