From 0199da610ebd3a58dc364af71538e63378226bad Mon Sep 17 00:00:00 2001 From: Tony Olagbaiye Date: Fri, 14 Jan 2022 21:29:04 +0000 Subject: [PATCH] fix bug from f2e711a --- account.cpp | 12 +- gcrypt.hh | 13 ++ omemo.cpp | 351 +++++++++++++++++++++------------------------------- omemo.hh | 8 +- signal.hh | 216 ++++++++++++++++++++++++++++---- 5 files changed, 355 insertions(+), 245 deletions(-) create mode 100644 gcrypt.hh diff --git a/account.cpp b/account.cpp index 53dc00d..c885b27 100644 --- a/account.cpp +++ b/account.cpp @@ -116,7 +116,7 @@ void account__add_device(struct t_account *account, new_device = account__search_device(account, device->id); if (!new_device) { - new_device = (struct t_account_device*)malloc(sizeof(*new_device)); + new_device = new struct t_account_device; new_device->id = device->id; new_device->name = strdup(device->name); new_device->label = device->label ? strdup(device->label) : NULL; @@ -158,7 +158,7 @@ void account__free_device(struct t_account *account, struct t_account_device *de if (device->name) free(device->name); - free(device); + delete device; account->devices = new_devices; } @@ -177,7 +177,7 @@ xmpp_stanza_t *account__get_devicelist(struct t_account *account) char id[64] = {0}; int i = 0; - device = (struct t_account_device*)malloc(sizeof(struct t_account_device)); + device = new struct t_account_device; device->id = account->omemo.device_id; snprintf(id, sizeof(id), "%u", device->id); @@ -190,7 +190,7 @@ xmpp_stanza_t *account__get_devicelist(struct t_account *account) free(device->label); free(device->name); - free(device); + delete device; for (device = account->devices; device; device = device->next_device) @@ -407,7 +407,7 @@ struct t_account *account__alloc(const char *name) return NULL; /* alloc memory for new account */ - new_account = (struct t_account*)malloc(sizeof(*new_account)); + new_account = new struct t_account; if (!new_account) { weechat_printf(NULL, @@ -575,7 +575,7 @@ void account__free(struct t_account *account) (account->next_account)->prev_account = account->prev_account; account__free_data(account); - free(account); + delete account; accounts = new_accounts; } diff --git a/gcrypt.hh b/gcrypt.hh new file mode 100644 index 0000000..916b613 --- /dev/null +++ b/gcrypt.hh @@ -0,0 +1,13 @@ +// This Source Code Form is subject to the terms of the Mozilla Public +// License, version 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#pragma once + +#include +#include +#include + +namespace gcrypt { + +} diff --git a/omemo.cpp b/omemo.cpp index ecee611..6b9982f 100644 --- a/omemo.cpp +++ b/omemo.cpp @@ -4,6 +4,7 @@ #include #include +#include #include #include #include @@ -11,13 +12,6 @@ #include #include #include -#include -#include -#include -#include -#include -#include -#include #include #include @@ -209,16 +203,12 @@ int cp_randomize(uint8_t *data, size_t len) { return SG_SUCCESS; } -int cp_random_generator(uint8_t *data, size_t len, void *user_data) { - (void) user_data; - +int cp_random_generator(uint8_t *data, size_t len, void *) { gcry_randomize(data, len, GCRY_STRONG_RANDOM); return SG_SUCCESS; } -int cp_hmac_sha256_init(void **hmac_context, const uint8_t *key, size_t key_len, void *user_data) { - (void) user_data; - +int cp_hmac_sha256_init(void **hmac_context, const uint8_t *key, size_t key_len, void *) { gcry_mac_hd_t* ctx = (gcry_mac_hd_t*)malloc(sizeof(gcry_mac_hd_t)); if (!ctx) return SG_ERR_NOMEM; @@ -237,9 +227,7 @@ int cp_hmac_sha256_init(void **hmac_context, const uint8_t *key, size_t key_len, return SG_SUCCESS; } -int cp_hmac_sha256_update(void *hmac_context, const uint8_t *data, size_t data_len, void *user_data) { - (void) user_data; - +int cp_hmac_sha256_update(void *hmac_context, const uint8_t *data, size_t data_len, void *) { gcry_mac_hd_t* ctx = (gcry_mac_hd_t*)hmac_context; if (gcry_mac_write(*ctx, data, data_len)) return SG_ERR_UNKNOWN; @@ -247,9 +235,7 @@ int cp_hmac_sha256_update(void *hmac_context, const uint8_t *data, size_t data_l return SG_SUCCESS; } -int cp_hmac_sha256_final(void *hmac_context, struct signal_buffer **output, void *user_data) { - (void) user_data; - +int cp_hmac_sha256_final(void *hmac_context, struct signal_buffer **output, void *) { size_t len = gcry_mac_get_algo_maclen(GCRY_MAC_HMAC_SHA256); auto md = std::unique_ptr(new uint8_t[len]); gcry_mac_hd_t* ctx = (gcry_mac_hd_t*)hmac_context; @@ -264,9 +250,7 @@ int cp_hmac_sha256_final(void *hmac_context, struct signal_buffer **output, void return SG_SUCCESS; } -void cp_hmac_sha256_cleanup(void *hmac_context, void *user_data) { - (void) user_data; - +void cp_hmac_sha256_cleanup(void *hmac_context, void *) { gcry_mac_hd_t* ctx = (gcry_mac_hd_t*)hmac_context; if (ctx) { gcry_mac_close(*ctx); @@ -274,9 +258,7 @@ void cp_hmac_sha256_cleanup(void *hmac_context, void *user_data) { } } -int cp_sha512_digest_init(void **digest_context, void *user_data) { - (void) user_data; - +int cp_sha512_digest_init(void **digest_context, void *) { gcry_md_hd_t* ctx = (gcry_md_hd_t*)malloc(sizeof(gcry_mac_hd_t)); if (!ctx) return SG_ERR_NOMEM; @@ -290,9 +272,7 @@ int cp_sha512_digest_init(void **digest_context, void *user_data) { return SG_SUCCESS; } -int cp_sha512_digest_update(void *digest_context, const uint8_t *data, size_t data_len, void *user_data) { - (void) user_data; - +int cp_sha512_digest_update(void *digest_context, const uint8_t *data, size_t data_len, void *) { gcry_md_hd_t* ctx = (gcry_md_hd_t*)digest_context; gcry_md_write(*ctx, data, data_len); @@ -300,9 +280,7 @@ int cp_sha512_digest_update(void *digest_context, const uint8_t *data, size_t da return SG_SUCCESS; } -int cp_sha512_digest_final(void *digest_context, struct signal_buffer **output, void *user_data) { - (void) user_data; - +int cp_sha512_digest_final(void *digest_context, struct signal_buffer **output, void *) { size_t len = gcry_md_get_algo_dlen(GCRY_MD_SHA512); gcry_md_hd_t* ctx = (gcry_md_hd_t*)digest_context; @@ -320,9 +298,7 @@ int cp_sha512_digest_final(void *digest_context, struct signal_buffer **output, return SG_SUCCESS; } -void cp_sha512_digest_cleanup(void *digest_context, void *user_data) { - (void) user_data; - +void cp_sha512_digest_cleanup(void *digest_context, void *) { gcry_md_hd_t* ctx = (gcry_md_hd_t*)digest_context; if (ctx) { gcry_md_close(*ctx); @@ -335,9 +311,7 @@ int cp_encrypt(struct signal_buffer **output, 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) { - (void) user_data; - + void *) { int algo, mode, error_code = SG_ERR_UNKNOWN; if (aes_cipher(cipher, key_len, &algo, &mode)) return SG_ERR_INVAL; @@ -412,9 +386,7 @@ int cp_decrypt(struct signal_buffer **output, 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) { - (void) user_data; - + void *) { int algo, mode, error_code = SG_ERR_UNKNOWN; *output = 0; if (aes_cipher(cipher, key_len, &algo, &mode)) return SG_ERR_INVAL; @@ -485,15 +457,15 @@ int iks_get_identity_key_pair(struct signal_buffer **public_data, signal_buffer MDB_val k_local_public_key = mdb_val_str("local_public_key"); MDB_val v_local_private_key, v_local_public_key; - if (mdb_txn_begin(omemo->db.env, NULL, MDB_RDONLY, &transaction)) { + if (mdb_txn_begin(omemo->db_env, NULL, MDB_RDONLY, &transaction)) { weechat_printf(NULL, "%sxmpp: failed to open lmdb transaction", weechat_prefix("error")); return -1; } - if (!mdb_get(transaction, omemo->db.dbi_omemo, + if (!mdb_get(transaction, omemo->dbi.omemo, &k_local_private_key, &v_local_private_key) && - !mdb_get(transaction, omemo->db.dbi_omemo, + !mdb_get(transaction, omemo->dbi.omemo, &k_local_public_key, &v_local_public_key)) { *private_data = signal_buffer_create((const uint8_t*)v_local_private_key.mv_data, v_local_private_key.mv_size); @@ -507,12 +479,10 @@ int iks_get_identity_key_pair(struct signal_buffer **public_data, signal_buffer } else { - struct ratchet_identity_key_pair *identity; + auto identity = libsignal::identity_key_pair::generate(omemo->context); - signal_protocol_key_helper_generate_identity_key_pair( - &identity, omemo->context.get()); - struct ec_private_key *private_key = ratchet_identity_key_pair_get_private(identity); - struct ec_public_key *public_key = ratchet_identity_key_pair_get_public(identity); + auto private_key = identity.get_private(); + auto public_key = identity.get_public(); ec_private_key_serialize(private_data, private_key); ec_public_key_serialize(public_data, public_key); @@ -523,15 +493,15 @@ int iks_get_identity_key_pair(struct signal_buffer **public_data, signal_buffer v_local_public_key.mv_size = signal_buffer_len(*public_data); mdb_txn_abort(transaction); - if (mdb_txn_begin(omemo->db.env, NULL, 0, &transaction)) { + if (mdb_txn_begin(omemo->db_env, NULL, 0, &transaction)) { weechat_printf(NULL, "%sxmpp: failed to open lmdb transaction", weechat_prefix("error")); return -1; } - if (mdb_put(transaction, omemo->db.dbi_omemo, + if (mdb_put(transaction, omemo->dbi.omemo, &k_local_private_key, &v_local_private_key, MDB_NOOVERWRITE) || - mdb_put(transaction, omemo->db.dbi_omemo, + mdb_put(transaction, omemo->dbi.omemo, &k_local_public_key, &v_local_public_key, MDB_NOOVERWRITE)) { weechat_printf(NULL, "%sxmpp: failed to write lmdb value", @@ -549,7 +519,8 @@ int iks_get_identity_key_pair(struct signal_buffer **public_data, signal_buffer v_local_private_key.mv_size); *public_data = signal_buffer_create((const uint8_t*)v_local_public_key.mv_data, v_local_public_key.mv_size); - omemo->identity.reset(identity); + + omemo->identity = identity; } return 0; @@ -566,13 +537,13 @@ int iks_get_local_registration_id(void *user_data, uint32_t *registration_id) MDB_val v_local_registration_id = mdb_val_sizeof(uint32_t); // Return the local client's registration ID - if (mdb_txn_begin(omemo->db.env, NULL, MDB_RDONLY, &transaction)) { + if (mdb_txn_begin(omemo->db_env, NULL, MDB_RDONLY, &transaction)) { weechat_printf(NULL, "%sxmpp: failed to open lmdb transaction", weechat_prefix("error")); return -1; } - if (!mdb_get(transaction, omemo->db.dbi_omemo, + if (!mdb_get(transaction, omemo->dbi.omemo, &k_local_registration_id, &v_local_registration_id)) { @@ -588,17 +559,17 @@ int iks_get_local_registration_id(void *user_data, uint32_t *registration_id) { uint32_t generated_id; signal_protocol_key_helper_generate_registration_id( - &generated_id, 0, omemo->context.get()); + &generated_id, 0, omemo->context); v_local_registration_id.mv_data = &generated_id; mdb_txn_abort(transaction); - if (mdb_txn_begin(omemo->db.env, NULL, 0, &transaction)) { + if (mdb_txn_begin(omemo->db_env, NULL, 0, &transaction)) { weechat_printf(NULL, "%sxmpp: failed to open lmdb transaction", weechat_prefix("error")); return -1; } - if (mdb_put(transaction, omemo->db.dbi_omemo, + if (mdb_put(transaction, omemo->dbi.omemo, &k_local_registration_id, &v_local_registration_id, MDB_NOOVERWRITE)) { @@ -639,13 +610,13 @@ int iks_save_identity(const struct signal_protocol_address *address, uint8_t *ke snprintf((char*)k_identity_key.mv_data, k_identity_key.mv_size + 1, "identity_key_%s_%u", address->name, address->device_id); - if (mdb_txn_begin(omemo->db.env, NULL, 0, &transaction)) { + if (mdb_txn_begin(omemo->db_env, NULL, 0, &transaction)) { weechat_printf(NULL, "%sxmpp: failed to open lmdb transaction", weechat_prefix("error")); return -1; } - if (mdb_put(transaction, omemo->db.dbi_omemo, &k_identity_key, + if (mdb_put(transaction, omemo->dbi.omemo, &k_identity_key, &v_identity_key, 0)) { weechat_printf(NULL, "%sxmpp: failed to write lmdb value", weechat_prefix("error")); @@ -682,13 +653,13 @@ int iks_is_trusted_identity(const struct signal_protocol_address *address, uint8 snprintf((char*)k_identity_key.mv_data, k_identity_key.mv_size + 1, "identity_key_%s_%u", address->name, address->device_id); - if (mdb_txn_begin(omemo->db.env, NULL, MDB_RDONLY, &transaction)) { + if (mdb_txn_begin(omemo->db_env, NULL, MDB_RDONLY, &transaction)) { weechat_printf(NULL, "%sxmpp: failed to open lmdb transaction", weechat_prefix("error")); return -1; } - if (mdb_get(transaction, omemo->db.dbi_omemo, &k_identity_key, + if (mdb_get(transaction, omemo->dbi.omemo, &k_identity_key, &v_identity_key)) { weechat_printf(NULL, "%sxmpp: failed to read lmdb value", weechat_prefix("error")); @@ -734,13 +705,13 @@ int pks_store_pre_key(uint32_t pre_key_id, uint8_t *record, size_t record_len, v snprintf((char*)k_pre_key.mv_data, k_pre_key.mv_size + 1, "pre_key_%-10u", pre_key_id); - if (mdb_txn_begin(omemo->db.env, NULL, 0, &transaction)) { + if (mdb_txn_begin(omemo->db_env, NULL, 0, &transaction)) { weechat_printf(NULL, "%sxmpp: failed to open lmdb transaction", weechat_prefix("error")); return -1; } - if (mdb_put(transaction, omemo->db.dbi_omemo, &k_pre_key, + if (mdb_put(transaction, omemo->dbi.omemo, &k_pre_key, &v_pre_key, 0)) { weechat_printf(NULL, "%sxmpp: failed to write lmdb value", weechat_prefix("error")); @@ -775,13 +746,13 @@ int pks_contains_pre_key(uint32_t pre_key_id, void *user_data) snprintf((char*)k_pre_key.mv_data, k_pre_key.mv_size + 1, "pre_key_%-10u", pre_key_id); - if (mdb_txn_begin(omemo->db.env, NULL, MDB_RDONLY, &transaction)) { + if (mdb_txn_begin(omemo->db_env, NULL, MDB_RDONLY, &transaction)) { weechat_printf(NULL, "%sxmpp: failed to open lmdb transaction", weechat_prefix("error")); return -1; } - if (mdb_get(transaction, omemo->db.dbi_omemo, &k_pre_key, + if (mdb_get(transaction, omemo->dbi.omemo, &k_pre_key, &v_pre_key)) { weechat_printf(NULL, "%sxmpp: failed to read lmdb value", weechat_prefix("error")); @@ -804,20 +775,20 @@ uint32_t pks_get_count(t_omemo *omemo, int increment) MDB_val k_pre_key_idx = mdb_val_str("pre_key_idx"); MDB_val v_pre_key_idx = mdb_val_intptr(&count); - if (mdb_txn_begin(omemo->db.env, NULL, 0, &transaction)) { + if (mdb_txn_begin(omemo->db_env, NULL, 0, &transaction)) { weechat_printf(NULL, "%sxmpp: failed to open lmdb transaction", weechat_prefix("error")); return -1; } - if (!mdb_get(transaction, omemo->db.dbi_omemo, + if (!mdb_get(transaction, omemo->dbi.omemo, &k_pre_key_idx, &v_pre_key_idx)) { if (increment) count += PRE_KEY_COUNT; } - if (mdb_put(transaction, omemo->db.dbi_omemo, + if (mdb_put(transaction, omemo->dbi.omemo, &k_pre_key_idx, &v_pre_key_idx, 0)) { weechat_printf(NULL, "%sxmpp: failed to read lmdb value", @@ -853,13 +824,13 @@ int pks_load_pre_key(struct signal_buffer **record, uint32_t pre_key_id, void *u snprintf((char*)k_pre_key.mv_data, k_pre_key.mv_size + 1, "pre_key_%-10u", pre_key_id); - if (mdb_txn_begin(omemo->db.env, NULL, 0, &transaction)) { + if (mdb_txn_begin(omemo->db_env, NULL, 0, &transaction)) { weechat_printf(NULL, "%sxmpp: failed to open lmdb transaction", weechat_prefix("error")); return -1; } - if (!mdb_get(transaction, omemo->db.dbi_omemo, + if (!mdb_get(transaction, omemo->dbi.omemo, &k_pre_key, &v_pre_key)) { *record = signal_buffer_create((const uint8_t*)v_pre_key.mv_data, v_pre_key.mv_size); @@ -879,7 +850,7 @@ int pks_load_pre_key(struct signal_buffer **record, uint32_t pre_key_id, void *u for (signal_protocol_key_helper_generate_pre_keys(&pre_keys_list, pks_get_count(omemo, 1), PRE_KEY_COUNT, - omemo->context.get()); pre_keys_list; + omemo->context); pre_keys_list; pre_keys_list = signal_protocol_key_helper_key_list_next(pre_keys_list)) { pre_key = signal_protocol_key_helper_key_list_element(pre_keys_list); @@ -913,13 +884,13 @@ int pks_remove_pre_key(uint32_t pre_key_id, void *user_data) snprintf((char*)k_pre_key.mv_data, k_pre_key.mv_size + 1, "pre_key_%-10u", pre_key_id); - if (mdb_txn_begin(omemo->db.env, NULL, 0, &transaction)) { + if (mdb_txn_begin(omemo->db_env, NULL, 0, &transaction)) { weechat_printf(NULL, "%sxmpp: failed to open lmdb transaction", weechat_prefix("error")); return -1; } - if (mdb_del(transaction, omemo->db.dbi_omemo, &k_pre_key, + if (mdb_del(transaction, omemo->dbi.omemo, &k_pre_key, &v_pre_key)) { weechat_printf(NULL, "%sxmpp: failed to erase lmdb value", weechat_prefix("error")); @@ -961,13 +932,13 @@ int spks_load_signed_pre_key(struct signal_buffer **record, uint32_t signed_pre_ snprintf((char*)k_signed_pre_key.mv_data, k_signed_pre_key.mv_size + 1, "signed_pre_key_%-10u", signed_pre_key_id); - if (mdb_txn_begin(omemo->db.env, NULL, 0, &transaction)) { + if (mdb_txn_begin(omemo->db_env, NULL, 0, &transaction)) { weechat_printf(NULL, "%sxmpp: failed to open lmdb transaction", weechat_prefix("error")); return -1; } - if (!mdb_get(transaction, omemo->db.dbi_omemo, + if (!mdb_get(transaction, omemo->dbi.omemo, &k_signed_pre_key, &v_signed_pre_key)) { *record = signal_buffer_create((const uint8_t*)v_signed_pre_key.mv_data, v_signed_pre_key.mv_size); @@ -983,13 +954,13 @@ int spks_load_signed_pre_key(struct signal_buffer **record, uint32_t signed_pre_ session_signed_pre_key *signed_pre_key = NULL; struct signal_buffer *serialized_key = NULL; - signal_protocol_key_helper_generate_signed_pre_key(&signed_pre_key, omemo->identity.get(), signed_pre_key_id, time(NULL), omemo->context.get()); + signal_protocol_key_helper_generate_signed_pre_key(&signed_pre_key, omemo->identity, signed_pre_key_id, time(NULL), omemo->context); session_signed_pre_key_serialize(&serialized_key, signed_pre_key); v_signed_pre_key.mv_data = signal_buffer_data(serialized_key); v_signed_pre_key.mv_size = signal_buffer_len(serialized_key); - if (mdb_put(transaction, omemo->db.dbi_omemo, + if (mdb_put(transaction, omemo->dbi.omemo, &k_signed_pre_key, &v_signed_pre_key, MDB_NOOVERWRITE)) { weechat_printf(NULL, "%sxmpp: failed to read lmdb value", @@ -1028,13 +999,13 @@ int spks_store_signed_pre_key(uint32_t signed_pre_key_id, uint8_t *record, size_ snprintf((char*)k_signed_pre_key.mv_data, k_signed_pre_key.mv_size + 1, "signed_pre_key_%-10u", signed_pre_key_id); - if (mdb_txn_begin(omemo->db.env, NULL, 0, &transaction)) { + if (mdb_txn_begin(omemo->db_env, NULL, 0, &transaction)) { weechat_printf(NULL, "%sxmpp: failed to open lmdb transaction", weechat_prefix("error")); return -1; } - if (mdb_put(transaction, omemo->db.dbi_omemo, &k_signed_pre_key, + if (mdb_put(transaction, omemo->dbi.omemo, &k_signed_pre_key, &v_signed_pre_key, 0)) { weechat_printf(NULL, "%sxmpp: failed to write lmdb value", weechat_prefix("error")); @@ -1069,13 +1040,13 @@ int spks_contains_signed_pre_key(uint32_t signed_pre_key_id, void *user_data) snprintf((char*)k_signed_pre_key.mv_data, k_signed_pre_key.mv_size + 1, "signed_pre_key_%-10u", signed_pre_key_id); - if (mdb_txn_begin(omemo->db.env, NULL, MDB_RDONLY, &transaction)) { + if (mdb_txn_begin(omemo->db_env, NULL, MDB_RDONLY, &transaction)) { weechat_printf(NULL, "%sxmpp: failed to open lmdb transaction", weechat_prefix("error")); return -1; } - if (mdb_get(transaction, omemo->db.dbi_omemo, &k_signed_pre_key, + if (mdb_get(transaction, omemo->dbi.omemo, &k_signed_pre_key, &v_signed_pre_key)) { mdb_txn_abort(transaction); goto cleanup; @@ -1105,13 +1076,13 @@ int spks_remove_signed_pre_key(uint32_t signed_pre_key_id, void *user_data) snprintf((char*)k_signed_pre_key.mv_data, k_signed_pre_key.mv_size + 1, "signed_pre_key_%-10u", signed_pre_key_id); - if (mdb_txn_begin(omemo->db.env, NULL, 0, &transaction)) { + if (mdb_txn_begin(omemo->db_env, NULL, 0, &transaction)) { weechat_printf(NULL, "%sxmpp: failed to open lmdb transaction", weechat_prefix("error")); return -1; } - if (mdb_del(transaction, omemo->db.dbi_omemo, &k_signed_pre_key, + if (mdb_del(transaction, omemo->dbi.omemo, &k_signed_pre_key, &v_signed_pre_key)) { weechat_printf(NULL, "%sxmpp: failed to erase lmdb value", weechat_prefix("error")); @@ -1163,15 +1134,15 @@ int ss_load_session_func(struct signal_buffer **record, signal_buffer **user_rec snprintf((char*)k_user.mv_data, k_user.mv_size + 1, "user_%u_%s", address->device_id, address->name); - if (mdb_txn_begin(omemo->db.env, NULL, MDB_RDONLY, &transaction)) { + if (mdb_txn_begin(omemo->db_env, NULL, MDB_RDONLY, &transaction)) { weechat_printf(NULL, "%sxmpp: failed to open lmdb transaction", weechat_prefix("error")); return -1; } - if (mdb_get(transaction, omemo->db.dbi_omemo, + if (mdb_get(transaction, omemo->dbi.omemo, &k_session, &v_session)/* || - mdb_get(transaction, omemo->db.dbi_omemo, + mdb_get(transaction, omemo->dbi.omemo, &k_user, &v_user)*/) { mdb_txn_abort(transaction); @@ -1208,13 +1179,13 @@ int ss_get_sub_device_sessions_func(signal_int_list **sessions, const char *name snprintf((char*)k_device_ids.mv_data, k_device_ids.mv_size + 1, "device_ids_%s", name); - if (mdb_txn_begin(omemo->db.env, NULL, MDB_RDONLY, &transaction)) { + if (mdb_txn_begin(omemo->db_env, NULL, MDB_RDONLY, &transaction)) { weechat_printf(NULL, "%sxmpp: failed to open lmdb transaction", weechat_prefix("error")); return -1; } - if (!mdb_get(transaction, omemo->db.dbi_omemo, + if (!mdb_get(transaction, omemo->dbi.omemo, &k_device_ids, &v_device_ids)) { char **argv; @@ -1282,15 +1253,15 @@ int ss_store_session_func(const struct signal_protocol_address *address, uint8_t snprintf((char*)k_user.mv_data, k_user.mv_size + 1, "user_%u_%s", address->device_id, address->name); - if (mdb_txn_begin(omemo->db.env, NULL, 0, &transaction)) { + if (mdb_txn_begin(omemo->db_env, NULL, 0, &transaction)) { weechat_printf(NULL, "%sxmpp: failed to open lmdb transaction", weechat_prefix("error")); return -1; } - if (mdb_put(transaction, omemo->db.dbi_omemo, + if (mdb_put(transaction, omemo->dbi.omemo, &k_session, &v_session, 0)/* || - mdb_put(transaction, omemo->db.dbi_omemo, + mdb_put(transaction, omemo->dbi.omemo, &k_user, &v_user, 0)*/) { weechat_printf(NULL, "%sxmpp: failed to write lmdb value", weechat_prefix("error")); @@ -1326,13 +1297,13 @@ int ss_contains_session_func(const struct signal_protocol_address *address, void snprintf((char*)k_session.mv_data, k_session.mv_size + 1, "session_%u_%s", address->device_id, address->name); - if (mdb_txn_begin(omemo->db.env, NULL, MDB_RDONLY, &transaction)) { + if (mdb_txn_begin(omemo->db_env, NULL, MDB_RDONLY, &transaction)) { weechat_printf(NULL, "%sxmpp: failed to open lmdb transaction", weechat_prefix("error")); return 0; } - if (mdb_get(transaction, omemo->db.dbi_omemo, &k_session, &v_session)) { + if (mdb_get(transaction, omemo->dbi.omemo, &k_session, &v_session)) { mdb_txn_abort(transaction); return 0; }; @@ -1358,13 +1329,13 @@ int ss_delete_session_func(const struct signal_protocol_address *address, void * snprintf((char*)k_session.mv_data, k_session.mv_size + 1, "session_%u_%s", address->device_id, address->name); - if (mdb_txn_begin(omemo->db.env, NULL, 0, &transaction)) { + if (mdb_txn_begin(omemo->db_env, NULL, 0, &transaction)) { weechat_printf(NULL, "%sxmpp: failed to open lmdb transaction", weechat_prefix("error")); return -1; } - if (mdb_del(transaction, omemo->db.dbi_omemo, &k_session, &v_session)) { + if (mdb_del(transaction, omemo->dbi.omemo, &k_session, &v_session)) { weechat_printf(NULL, "%sxmpp: failed to erase lmdb value", weechat_prefix("error")); goto cleanup; @@ -1449,13 +1420,13 @@ int sks_store_sender_key(const signal_protocol_sender_key_name *sender_key_name, snprintf((char*)k_device_ids.mv_data, k_device_ids.mv_size + 1, "device_ids_%s", sender_key_name->sender.name); - if (mdb_txn_begin(omemo->db.env, NULL, 0, &transaction)) { + if (mdb_txn_begin(omemo->db_env, NULL, 0, &transaction)) { weechat_printf(NULL, "%sxmpp: failed to open lmdb transaction", weechat_prefix("error")); return -1; } - if (!mdb_get(transaction, omemo->db.dbi_omemo, + if (!mdb_get(transaction, omemo->dbi.omemo, &k_device_ids, &v_device_ids)) { char **argv; @@ -1488,11 +1459,11 @@ int sks_store_sender_key(const signal_protocol_sender_key_name *sender_key_name, v_device_ids.mv_size = strlen(device_list) + 1; } - if (mdb_put(transaction, omemo->db.dbi_omemo, + if (mdb_put(transaction, omemo->dbi.omemo, &k_sender_key, &v_sender_key, 0)/* || - mdb_put(transaction, omemo->db.dbi_omemo, + mdb_put(transaction, omemo->dbi.omemo, &k_user, &v_user, 0)*/ || - mdb_put(transaction, omemo->db.dbi_omemo, + mdb_put(transaction, omemo->dbi.omemo, &k_device_ids, &v_device_ids, 0)) { weechat_printf(NULL, "%sxmpp: failed to write lmdb value", weechat_prefix("error")); @@ -1547,15 +1518,15 @@ int sks_load_sender_key(struct signal_buffer **record, signal_buffer **user_reco sender_key_name->sender.device_id, sender_key_name->sender.name); - if (mdb_txn_begin(omemo->db.env, NULL, 0, &transaction)) { + if (mdb_txn_begin(omemo->db_env, NULL, 0, &transaction)) { weechat_printf(NULL, "%sxmpp: failed to open lmdb transaction", weechat_prefix("error")); return -1; } - if (mdb_get(transaction, omemo->db.dbi_omemo, + if (mdb_get(transaction, omemo->dbi.omemo, &k_sender_key, &v_sender_key)/* && - mdb_get(transaction, omemo->db.dbi_omemo, + mdb_get(transaction, omemo->dbi.omemo, &k_user, &v_user)*/) { *record = signal_buffer_create((const uint8_t*)v_sender_key.mv_data, v_sender_key.mv_size); @@ -1612,13 +1583,13 @@ int dls_store_devicelist(const char *jid, signal_int_list *devicelist, t_omemo * v_devicelist.mv_size = strlen((const char*)v_devicelist.mv_data); for (char **device = (char **)devices; *device; device++) free(*device); - if (mdb_txn_begin(omemo->db.env, NULL, 0, &transaction)) { + if (mdb_txn_begin(omemo->db_env, NULL, 0, &transaction)) { weechat_printf(NULL, "%sxmpp: failed to open lmdb transaction", weechat_prefix("error")); return -1; } - if (mdb_put(transaction, omemo->db.dbi_omemo, &k_devicelist, + if (mdb_put(transaction, omemo->dbi.omemo, &k_devicelist, &v_devicelist, 0)) { weechat_printf(NULL, "%sxmpp: failed to write lmdb value", weechat_prefix("error")); @@ -1639,33 +1610,13 @@ cleanup: int dls_load_devicelist(signal_int_list **devicelist, const char *jid, t_omemo *omemo) { - MDB_txn *transaction = NULL; - MDB_val k_devicelist = { - .mv_size = strlen("devicelist_") + strlen(jid), - .mv_data = NULL, - }; - MDB_val v_devicelist; - - k_devicelist.mv_data = malloc(sizeof(char) * ( - k_devicelist.mv_size + 1)); - k_devicelist.mv_size = - snprintf((char*)k_devicelist.mv_data, k_devicelist.mv_size + 1, - "devicelist_%s", jid); + auto transaction = lmdb::txn::begin(omemo->db_env); + std::string k_devicelist = fmt::format("devicelist_{}", jid); + std::string_view v_devicelist; + omemo->dbi.omemo.get(transaction, k_devicelist, v_devicelist); int devices_len = 0; - char **devices = weechat_string_split((const char*)v_devicelist.mv_data, ";", NULL, 0, 0, &devices_len); - - if (mdb_txn_begin(omemo->db.env, NULL, MDB_RDONLY, &transaction)) { - weechat_printf(NULL, "%sxmpp: failed to open lmdb transaction", - weechat_prefix("error")); - return -1; - } - - if (mdb_get(transaction, omemo->db.dbi_omemo, - &k_devicelist, &v_devicelist)) - { - goto cleanup; - } + char **devices = weechat_string_split(v_devicelist.data(), ";", NULL, 0, 0, &devices_len); *devicelist = signal_int_list_alloc(); for (int i = 0; i < devices_len; i++) @@ -1675,16 +1626,9 @@ int dls_load_devicelist(signal_int_list **devicelist, const char *jid, t_omemo * } weechat_string_free_split(devices); - if (mdb_txn_commit(transaction)) { - weechat_printf(NULL, "%sxmpp: failed to close lmdb transaction", - weechat_prefix("error")); - goto cleanup; - }; + transaction.commit(); return 0; -cleanup: - mdb_txn_abort(transaction); - return -1; } int bks_store_bundle(struct signal_protocol_address *address, @@ -1716,17 +1660,12 @@ int bks_store_bundle(struct signal_protocol_address *address, snprintf(signed_pre_key_buffers[i], keylen + 1, "%s.%s", signed_pre_key->id, signed_pre_key->public_key); - int ret; uint8_t *signing_key_buf; size_t signing_key_len = base64_decode(identity_key, strlen(identity_key), &signing_key_buf); - ec_public_key *signing_key; - if ((ret = curve_decode_point(&signing_key, signing_key_buf, - signing_key_len, omemo->context.get()))) { - weechat_printf(NULL, "%sxmpp: failed to decode ED25519 prekey", - weechat_prefix("error")); - return -1; - }; + libsignal::public_key signing_key(signing_key_buf, + signing_key_len, omemo->context); + uint8_t *signed_key_buf; size_t signed_key_len = base64_decode(signed_pre_key->public_key, strlen(signed_pre_key->public_key), &signed_key_buf); @@ -1792,20 +1731,20 @@ int bks_store_bundle(struct signal_protocol_address *address, .mv_data = (char*)identity_key, }; - if (mdb_txn_begin(omemo->db.env, NULL, 0, &transaction)) { + if (mdb_txn_begin(omemo->db_env, NULL, 0, &transaction)) { weechat_printf(NULL, "%sxmpp: failed to open lmdb transaction", weechat_prefix("error")); return -1; } int ret; - if ((ret = mdb_put(transaction, omemo->db.dbi_omemo, &k_bundle_pk, + if ((ret = mdb_put(transaction, omemo->dbi.omemo, &k_bundle_pk, &v_bundle_pk, 0)) || - (ret = mdb_put(transaction, omemo->db.dbi_omemo, &k_bundle_sk, + (ret = mdb_put(transaction, omemo->dbi.omemo, &k_bundle_sk, &v_bundle_sk, 0)) || - (ret = mdb_put(transaction, omemo->db.dbi_omemo, &k_bundle_sg, + (ret = mdb_put(transaction, omemo->dbi.omemo, &k_bundle_sg, &v_bundle_sg, 0)) || - (ret = mdb_put(transaction, omemo->db.dbi_omemo, &k_bundle_ik, + (ret = mdb_put(transaction, omemo->dbi.omemo, &k_bundle_ik, &v_bundle_ik, 0))) { weechat_printf(NULL, "%sxmpp: failed to write lmdb value '%s'@%u: %s", weechat_prefix("error"), v_bundle_pk.mv_data, v_bundle_pk.mv_size, mdb_strerror(ret)); @@ -1861,7 +1800,7 @@ int bks_load_bundle(session_pre_key_bundle **bundle, struct signal_protocol_addr MDB_val v_bundle_ik; int ret; - if ((ret = mdb_txn_begin(omemo->db.env, NULL, MDB_RDONLY, &transaction))) { + if ((ret = mdb_txn_begin(omemo->db_env, NULL, MDB_RDONLY, &transaction))) { weechat_printf(NULL, "%sxmpp: failed to open lmdb transaction", weechat_prefix("error")); return -1; @@ -1880,13 +1819,13 @@ int bks_load_bundle(session_pre_key_bundle **bundle, struct signal_protocol_addr struct signal_buffer *signature; uint8_t *key_buf; size_t key_len; - if ((ret = mdb_get(transaction, omemo->db.dbi_omemo, + if ((ret = mdb_get(transaction, omemo->dbi.omemo, &k_bundle_pk, &v_bundle_pk)) || - (ret = mdb_get(transaction, omemo->db.dbi_omemo, + (ret = mdb_get(transaction, omemo->dbi.omemo, &k_bundle_sk, &v_bundle_sk)) || - (ret = mdb_get(transaction, omemo->db.dbi_omemo, + (ret = mdb_get(transaction, omemo->dbi.omemo, &k_bundle_sg, &v_bundle_sg)) || - (ret = mdb_get(transaction, omemo->db.dbi_omemo, + (ret = mdb_get(transaction, omemo->dbi.omemo, &k_bundle_ik, &v_bundle_ik))) { goto cleanup; @@ -1902,7 +1841,7 @@ int bks_load_bundle(session_pre_key_bundle **bundle, struct signal_protocol_addr char *key_data = (char *)memchr(bundle_pk, '.', 10 + 1) + 1; uint8_t *key_buf; size_t key_len = base64_decode(key_data, strlen(key_data), &key_buf); - if ((ret = curve_decode_point(&pre_key, key_buf, key_len, omemo->context.get()))) { + if ((ret = curve_decode_point(&pre_key, key_buf, key_len, omemo->context))) { weechat_printf(NULL, "%sxmpp: failed to decode ED25519 prekey", weechat_prefix("error")); goto cleanup; @@ -1916,7 +1855,7 @@ int bks_load_bundle(session_pre_key_bundle **bundle, struct signal_protocol_addr char *key_data = (char *)memchr(bundle_sk, '.', 10 + 1) + 1; uint8_t *key_buf; size_t key_len = base64_decode(key_data, strlen(key_data), &key_buf); - if ((ret = curve_decode_point(&signed_pre_key, key_buf, key_len, omemo->context.get()))) { + if ((ret = curve_decode_point(&signed_pre_key, key_buf, key_len, omemo->context))) { weechat_printf(NULL, "%sxmpp: failed to decode ED25519 signed prekey", weechat_prefix("error")); goto cleanup; @@ -1925,7 +1864,7 @@ int bks_load_bundle(session_pre_key_bundle **bundle, struct signal_protocol_addr sig_len = base64_decode((const char*)v_bundle_sg.mv_data, v_bundle_sg.mv_size, &sig_buf); signature = signal_buffer_create(sig_buf, sig_len); key_len = base64_decode((const char*)v_bundle_ik.mv_data, v_bundle_ik.mv_size, &key_buf); - if ((ret = curve_decode_point(&identity_key, key_buf, key_len, omemo->context.get()))) { + if ((ret = curve_decode_point(&identity_key, key_buf, key_len, omemo->context))) { weechat_printf(NULL, "%sxmpp: failed to decode ED25519 identity key", weechat_prefix("error")); goto cleanup; @@ -1987,7 +1926,7 @@ xmpp_stanza_t *omemo::get_bundle(xmpp_ctx_t *context, char *from, char *to) else num_keys++; session_pre_key *pre_key = NULL; session_pre_key_deserialize(&pre_key, signal_buffer_data(record), - signal_buffer_len(record), omemo->context.get()); + signal_buffer_len(record), omemo->context); if (pre_key == 0) (*((int*)0))++; signal_buffer_free(record); keypair = session_pre_key_get_key_pair(pre_key); @@ -2015,7 +1954,7 @@ xmpp_stanza_t *omemo::get_bundle(xmpp_ctx_t *context, char *from, char *to) session_signed_pre_key *signed_pre_key; session_signed_pre_key_deserialize(&signed_pre_key, signal_buffer_data(record), signal_buffer_len(record), - omemo->context.get()); + omemo->context); signal_buffer_free(record); uint32_t signed_pre_key_id = session_signed_pre_key_get_id(signed_pre_key); keypair = session_signed_pre_key_get_key_pair(signed_pre_key); @@ -2077,14 +2016,13 @@ xmpp_stanza_t *omemo::get_bundle(xmpp_ctx_t *context, char *from, char *to) void omemo::init(struct t_gui_buffer *buffer, const char *account_name) { - gcry_check_version(nullptr); + if (!gcry_check_version(GCRYPT_VERSION)) + throw std::runtime_error("GCrypt: library version mismatch"); auto omemo = this; - struct signal_context *context; - signal_context_create(&context, buffer); - omemo->context.reset(context); - signal_context_set_log_function(omemo->context.get(), &log_emit_weechat); + omemo->context.create(buffer); + omemo->context.set_log_function(&log_emit_weechat); try { omemo->db_path = std::shared_ptr( @@ -2092,22 +2030,21 @@ void omemo::init(struct t_gui_buffer *buffer, const char *account_name) NULL, NULL, NULL), &free).get(); - lmdb::env &env = omemo->db.env; + lmdb::env &env = omemo->db_env; env = lmdb::env::create(); - env.open(omemo->db_path.data(), MDB_NOSUBDIR, 0664); env.set_max_dbs(50); env.set_mapsize((size_t)1048576 * 8000); // 8000MB map for valgrind env.open(omemo->db_path.data(), MDB_NOSUBDIR, 0664); - lmdb::txn parentTransaction(nullptr); - lmdb::txn transaction = lmdb::txn::begin(omemo->db.env, parentTransaction); + lmdb::txn parentTransaction{nullptr}; + lmdb::txn transaction = lmdb::txn::begin(omemo->db_env, parentTransaction); std::string db_name = fmt::format("omemo_{}", account_name); - omemo->db.dbi_omemo = lmdb::dbi::open(transaction, db_name.data(), MDB_CREATE); + omemo->dbi.omemo = lmdb::dbi::open(transaction, db_name.data(), MDB_CREATE); transaction.commit(); } catch (const std::exception& ex) { - auto format = fmt::format("%sxmpp: lmdb failure {}", ex.what()); + auto format = fmt::format("%sxmpp: lmdb failure - {}", ex.what()); weechat_printf(NULL, format.data(), weechat_prefix("error")); return; } @@ -2127,12 +2064,10 @@ void omemo::init(struct t_gui_buffer *buffer, const char *account_name) .user_data = omemo, }; - signal_context_set_crypto_provider(omemo->context.get(), &crypto_provider); - signal_context_set_locking_functions(omemo->context.get(), &lock_function, &unlock_function); + omemo->context.set_crypto_provider(&crypto_provider); + omemo->context.set_locking_functions(&lock_function, &unlock_function); - struct signal_protocol_store_context *store_context; - signal_protocol_store_context_create(&store_context, omemo->context.get()); - omemo->store_context.reset(store_context); + omemo->store_context.create(omemo->context); struct signal_protocol_identity_key_store identity_key_store = { .get_identity_key_pair = &iks_get_identity_key_pair, @@ -2143,8 +2078,7 @@ void omemo::init(struct t_gui_buffer *buffer, const char *account_name) .user_data = omemo, }; - signal_protocol_store_context_set_identity_key_store( - omemo->store_context.get(), &identity_key_store); + omemo->store_context.set_identity_key_store(&identity_key_store); struct signal_protocol_pre_key_store pre_key_store = { .load_pre_key = &pks_load_pre_key, @@ -2155,8 +2089,7 @@ void omemo::init(struct t_gui_buffer *buffer, const char *account_name) .user_data = omemo, }; - signal_protocol_store_context_set_pre_key_store( - omemo->store_context.get(), &pre_key_store); + omemo->store_context.set_pre_key_store(&pre_key_store); struct signal_protocol_signed_pre_key_store signed_pre_key_store = { .load_signed_pre_key = &spks_load_signed_pre_key, @@ -2167,8 +2100,7 @@ void omemo::init(struct t_gui_buffer *buffer, const char *account_name) .user_data = omemo, }; - signal_protocol_store_context_set_signed_pre_key_store( - omemo->store_context.get(), &signed_pre_key_store); + omemo->store_context.set_signed_pre_key_store(&signed_pre_key_store); struct signal_protocol_session_store session_store = { .load_session_func = &ss_load_session_func, @@ -2181,8 +2113,7 @@ void omemo::init(struct t_gui_buffer *buffer, const char *account_name) .user_data = omemo, }; - signal_protocol_store_context_set_session_store( - omemo->store_context.get(), &session_store); + omemo->store_context.set_session_store(&session_store); struct signal_protocol_sender_key_store sender_key_store = { .store_sender_key = &sks_store_sender_key, @@ -2191,22 +2122,17 @@ void omemo::init(struct t_gui_buffer *buffer, const char *account_name) .user_data = omemo, }; - signal_protocol_store_context_set_sender_key_store( - omemo->store_context.get(), &sender_key_store); + omemo->store_context.set_sender_key_store(&sender_key_store); struct signal_buffer *public_data, *private_data; iks_get_local_registration_id(omemo, &omemo->device_id); if (!iks_get_identity_key_pair(&public_data, &private_data, omemo)) { - struct ec_public_key *public_key = NULL; - struct ec_private_key *private_key = NULL; - curve_decode_point(&public_key, signal_buffer_data(public_data), - signal_buffer_len(public_data), omemo->context.get()); - curve_decode_private_point(&private_key, signal_buffer_data(private_data), - signal_buffer_len(private_data), omemo->context.get()); - struct ratchet_identity_key_pair *key_pair; - ratchet_identity_key_pair_create(&key_pair, public_key, private_key); - omemo->identity.reset(key_pair); + libsignal::public_key public_key(signal_buffer_data(public_data), + signal_buffer_len(public_data), omemo->context); + libsignal::private_key private_key(signal_buffer_data(private_data), + signal_buffer_len(private_data), omemo->context); + omemo->identity.create(public_key, private_key); } weechat_printf(buffer, "%somemo: device = %d", weechat_prefix("info"), omemo->device_id); @@ -2309,12 +2235,11 @@ void omemo::handle_bundle(const char *jid, uint32_t device_id, struct signal_protocol_address address = { .name = jid, .name_len = strlen(jid), .device_id = (int32_t)device_id }; { - ec_public_key *key; uint8_t *key_buf; size_t key_len = base64_decode(identity_key, strlen(identity_key), &key_buf); - curve_decode_point(&key, key_buf, key_len, omemo->context.get()); - signal_protocol_identity_save_identity(omemo->store_context.get(), + libsignal::public_key key(key_buf, key_len, omemo->context); + signal_protocol_identity_save_identity(omemo->store_context, &address, key); } bks_store_bundle(&address, pre_keys, signed_pre_keys, @@ -2377,7 +2302,7 @@ char *omemo::decode(struct t_account *account, const char *jid, if (key_prekey) { pre_key_signal_message *pre_key_message = NULL; if ((ret = pre_key_signal_message_deserialize(&pre_key_message, - key_data, key_len, omemo->context.get()))) return NULL; + key_data, key_len, omemo->context))) return NULL; ec_public_key *identity_key = pre_key_signal_message_get_identity_key(pre_key_message); //uint32_t device_id = pre_key_signal_message_get_registration_id(pre_key_message); //uint32_t pre_key_id = pre_key_signal_message_get_pre_key_id(pre_key_message); @@ -2390,17 +2315,17 @@ char *omemo::decode(struct t_account *account, const char *jid, signal_buffer_len(identity_buf), omemo))) return NULL; struct session_cipher *cipher; - if ((ret = session_cipher_create(&cipher, omemo->store_context.get(), - &address, omemo->context.get()))) return NULL; + if ((ret = session_cipher_create(&cipher, omemo->store_context, + &address, omemo->context))) return NULL; if ((ret = session_cipher_decrypt_pre_key_signal_message(cipher, pre_key_message, 0, &aes_key))) return NULL; } else { if ((ret = signal_message_deserialize(&key_message, - key_data, key_len, omemo->context.get()))) return NULL; + key_data, key_len, omemo->context))) return NULL; struct session_cipher *cipher; - if ((ret = session_cipher_create(&cipher, omemo->store_context.get(), - &address, omemo->context.get()))) return NULL; + if ((ret = session_cipher_create(&cipher, omemo->store_context, + &address, omemo->context))) return NULL; if ((ret = session_cipher_decrypt_signal_message(cipher, key_message, 0, &aes_key))) return NULL; } @@ -2506,6 +2431,8 @@ xmpp_stanza_t *omemo::encode(struct t_account *account, const char *jid, for (size_t i = 0; i < signal_int_list_size(devicelist); i++) { uint32_t device_id = signal_int_list_at(devicelist, i); + weechat_printf(NULL, "omemo: trying device %u for %s", device_id, jid); + if (!device_id) continue; struct signal_protocol_address address = { .name = target, .name_len = strlen(target), .device_id = (int32_t)device_id}; @@ -2518,15 +2445,15 @@ xmpp_stanza_t *omemo::encode(struct t_account *account, const char *jid, struct session_builder *builder = NULL; if (((ret = ss_contains_session_func(&address, omemo))) <= 0) { - session_pre_key_bundle *bundle; + struct session_pre_key_bundle *bundle; if ((ret = bks_load_bundle(&bundle, &address, omemo))) continue; - if ((ret = session_builder_create(&builder, omemo->store_context.get(), &address, omemo->context.get()))) continue; + if ((ret = session_builder_create(&builder, omemo->store_context, &address, omemo->context))) continue; if ((ret = session_builder_process_pre_key_bundle(builder, bundle))) continue; } struct session_cipher *cipher; - if ((ret = session_cipher_create(&cipher, omemo->store_context.get(), &address, omemo->context.get()))) continue; + if ((ret = session_cipher_create(&cipher, omemo->store_context, &address, omemo->context))) continue; struct ciphertext_message *signal_message; if ((ret = session_cipher_encrypt(cipher, key_and_tag, AES_KEY_SIZE+tag_len, &signal_message))) continue; @@ -2545,7 +2472,8 @@ xmpp_stanza_t *omemo::encode(struct t_account *account, const char *jid, xmpp_stanza_add_child(header, header__key); xmpp_stanza_release(header__key); - keycount++; + if (target == jid) + keycount++; signal_buffer_free(record); //SIGNAL_UNREF(signal_message); @@ -2558,7 +2486,10 @@ xmpp_stanza_t *omemo::encode(struct t_account *account, const char *jid, } free(key_and_tag); - if (keycount == 0) return NULL; + if (keycount == 0) { + weechat_printf(NULL, "omemo: no keys for %s", jid); + return NULL; + } xmpp_stanza_t *header__iv = xmpp_stanza_new(account->context); xmpp_stanza_set_name(header__iv, "iv"); diff --git a/omemo.hh b/omemo.hh index 73b9b9e..703df7c 100644 --- a/omemo.hh +++ b/omemo.hh @@ -29,10 +29,10 @@ struct omemo libsignal::context context; libsignal::store_context store_context; - struct { - lmdb::env env; - lmdb::dbi dbi_omemo; - } db; + lmdb::env db_env = nullptr; + struct dbi { + lmdb::dbi omemo; + } dbi; std::string db_path; libsignal::identity_key_pair identity; diff --git a/signal.hh b/signal.hh index 3025e78..80e486b 100644 --- a/signal.hh +++ b/signal.hh @@ -4,9 +4,17 @@ #pragma once +#include #include #include +#include #include +#include +#include +#include +#include +#include +#include namespace libsignal { @@ -15,43 +23,201 @@ namespace libsignal { void operator() (T *ptr) { SIGNAL_UNREF(ptr); } }; - template<> - struct deleter { - void operator() (struct signal_context *ptr) - { signal_context_destroy(ptr); } + template + using object = std::unique_ptr>; + + template + class type { + private: + T *_ptr; + + public: + typedef T* pointer_type; + + inline explicit type() : _ptr(nullptr) { + } + + template + inline explicit type(Args&&... args) : type() { + f_create(&_ptr, std::forward(args)...); + } + + inline ~type() { + if (_ptr) + f_destroy(reinterpret_cast(_ptr)); + _ptr = nullptr; + } + + template + inline void create(Args&&... args) { + if (_ptr) + f_destroy(reinterpret_cast(_ptr)); + _ptr = nullptr; + f_create(&_ptr, std::forward(args)...); + } + + inline operator bool() const { return _ptr; } + + inline operator T*() { return _ptr; } + + inline operator const T*() const { return _ptr; } + + protected: + inline type(T *ptr) { + _ptr = ptr; + } + + template>>> + inline void call(Args&&... args) { + int ret = func(*this, std::forward(args)...); + if (ret != success) throw std::runtime_error( + fmt::format("Signal Error: expected {}, was {}", success, ret)); + } + + template>>> + inline std::invoke_result::type + call(Args&&... args) { + return func(*this, std::forward(args)...); + } }; - template<> - struct deleter { - void operator() (struct signal_protocol_store_context *ptr) - { signal_protocol_store_context_destroy(ptr); } + typedef type context_type; + class context : public context_type { + public: + using context_type::context_type; + + context& operator =(const context &other) = delete; + context& operator =(context &&other) = default; + + inline auto set_log_function(auto &&...args) { + return call(args...); + } + + inline auto set_crypto_provider(auto &&...args) { + return call(args...); + } + + inline auto set_locking_functions(auto &&...args) { + return call(args...); + } }; - template<> - struct deleter { - void operator() (struct ratchet_identity_key_pair *ptr) - { ratchet_identity_key_pair_destroy( - reinterpret_cast(ptr)); } + typedef type store_context_type; + class store_context : public store_context_type { + public: + using store_context_type::store_context_type; + + inline auto set_identity_key_store(auto &&...args) { + return call(args...); + } + + inline auto set_pre_key_store(auto &&...args) { + return call(args...); + } + + inline auto set_signed_pre_key_store(auto &&...args) { + return call(args...); + } + + inline auto set_session_store(auto &&...args) { + return call(args...); + } + + inline auto set_sender_key_store(auto &&...args) { + return call(args...); + } }; - template - using object = std::unique_ptr>; + typedef type public_key_type; + class public_key : public public_key_type { + public: + using public_key_type::public_key_type; + + inline static public_key deserialize(auto &&...args) { + pointer_type pointer; + ec_public_key_deserialize(&pointer, args...); + return public_key(pointer); + } - template - object make(int (*fun)(T**,Args...), Args... args) { - T *result; - fun(&result, args...); - return object(result); + inline auto serialize(auto &&...args) { + return call(args...); + } + + friend class identity_key_pair; }; - typedef object context; + typedef type private_key_type; + class private_key : public private_key_type { + public: + using private_key_type::private_key_type; + + inline static private_key deserialize(auto &&...args) { + pointer_type pointer; + ec_private_key_deserialize(&pointer, args...); + return private_key(pointer); + } - typedef object store_context; + inline auto serialize(auto &&...args) { + return call(args...); + } - typedef object identity_key_pair; + friend class identity_key_pair; + }; + + typedef type identity_key_pair_type; + class identity_key_pair : public identity_key_pair_type { + public: + using identity_key_pair_type::identity_key_pair_type; - typedef object public_key; + inline static identity_key_pair generate(auto &&...args) { + pointer_type pointer; + signal_protocol_key_helper_generate_identity_key_pair(&pointer, args...); + return identity_key_pair(pointer); + } - typedef object private_key; + inline public_key get_public(auto &&...args) { + return call(args...); + } + + inline private_key get_private(auto &&...args) { + return call(args...); + } + }; }