master
Tony Olagbaiye 3 years ago
parent bb375918ee
commit 0199da610e
No known key found for this signature in database
GPG Key ID: 9E2FF3BDEBDFC910

@ -116,7 +116,7 @@ void account__add_device(struct t_account *account,
new_device = account__search_device(account, device->id); new_device = account__search_device(account, device->id);
if (!new_device) 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->id = device->id;
new_device->name = strdup(device->name); new_device->name = strdup(device->name);
new_device->label = device->label ? strdup(device->label) : NULL; 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) if (device->name)
free(device->name); free(device->name);
free(device); delete device;
account->devices = new_devices; account->devices = new_devices;
} }
@ -177,7 +177,7 @@ xmpp_stanza_t *account__get_devicelist(struct t_account *account)
char id[64] = {0}; char id[64] = {0};
int i = 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; device->id = account->omemo.device_id;
snprintf(id, sizeof(id), "%u", 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->label);
free(device->name); free(device->name);
free(device); delete device;
for (device = account->devices; device; for (device = account->devices; device;
device = device->next_device) device = device->next_device)
@ -407,7 +407,7 @@ struct t_account *account__alloc(const char *name)
return NULL; return NULL;
/* alloc memory for new account */ /* alloc memory for new account */
new_account = (struct t_account*)malloc(sizeof(*new_account)); new_account = new struct t_account;
if (!new_account) if (!new_account)
{ {
weechat_printf(NULL, weechat_printf(NULL,
@ -575,7 +575,7 @@ void account__free(struct t_account *account)
(account->next_account)->prev_account = account->prev_account; (account->next_account)->prev_account = account->prev_account;
account__free_data(account); account__free_data(account);
free(account); delete account;
accounts = new_accounts; accounts = new_accounts;
} }

@ -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 <memory>
#include <functional>
#include <gcrypt.h>
namespace gcrypt {
}

@ -4,6 +4,7 @@
#include <fmt/core.h> #include <fmt/core.h>
#include <memory> #include <memory>
#include <stdexcept>
#include <stdlib.h> #include <stdlib.h>
#include <stdint.h> #include <stdint.h>
#include <sys/param.h> #include <sys/param.h>
@ -11,13 +12,6 @@
#include <math.h> #include <math.h>
#include <limits.h> #include <limits.h>
#include <gcrypt.h> #include <gcrypt.h>
#include <signal_protocol.h>
#include <key_helper.h>
#include <session_builder.h>
#include <session_cipher.h>
#include <session_pre_key.h>
#include <protocol.h>
#include <curve.h>
#include <strophe.h> #include <strophe.h>
#include <weechat/weechat-plugin.h> #include <weechat/weechat-plugin.h>
@ -209,16 +203,12 @@ int cp_randomize(uint8_t *data, size_t len) {
return SG_SUCCESS; return SG_SUCCESS;
} }
int cp_random_generator(uint8_t *data, size_t len, void *user_data) { int cp_random_generator(uint8_t *data, size_t len, void *) {
(void) user_data;
gcry_randomize(data, len, GCRY_STRONG_RANDOM); gcry_randomize(data, len, GCRY_STRONG_RANDOM);
return SG_SUCCESS; return SG_SUCCESS;
} }
int cp_hmac_sha256_init(void **hmac_context, const uint8_t *key, size_t key_len, void *user_data) { int cp_hmac_sha256_init(void **hmac_context, const uint8_t *key, size_t key_len, void *) {
(void) user_data;
gcry_mac_hd_t* ctx = (gcry_mac_hd_t*)malloc(sizeof(gcry_mac_hd_t)); gcry_mac_hd_t* ctx = (gcry_mac_hd_t*)malloc(sizeof(gcry_mac_hd_t));
if (!ctx) return SG_ERR_NOMEM; 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; return SG_SUCCESS;
} }
int cp_hmac_sha256_update(void *hmac_context, const uint8_t *data, size_t data_len, void *user_data) { int cp_hmac_sha256_update(void *hmac_context, const uint8_t *data, size_t data_len, void *) {
(void) user_data;
gcry_mac_hd_t* ctx = (gcry_mac_hd_t*)hmac_context; gcry_mac_hd_t* ctx = (gcry_mac_hd_t*)hmac_context;
if (gcry_mac_write(*ctx, data, data_len)) return SG_ERR_UNKNOWN; 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; return SG_SUCCESS;
} }
int cp_hmac_sha256_final(void *hmac_context, struct signal_buffer **output, void *user_data) { int cp_hmac_sha256_final(void *hmac_context, struct signal_buffer **output, void *) {
(void) user_data;
size_t len = gcry_mac_get_algo_maclen(GCRY_MAC_HMAC_SHA256); size_t len = gcry_mac_get_algo_maclen(GCRY_MAC_HMAC_SHA256);
auto md = std::unique_ptr<uint8_t[]>(new uint8_t[len]); auto md = std::unique_ptr<uint8_t[]>(new uint8_t[len]);
gcry_mac_hd_t* ctx = (gcry_mac_hd_t*)hmac_context; 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; return SG_SUCCESS;
} }
void cp_hmac_sha256_cleanup(void *hmac_context, void *user_data) { void cp_hmac_sha256_cleanup(void *hmac_context, void *) {
(void) user_data;
gcry_mac_hd_t* ctx = (gcry_mac_hd_t*)hmac_context; gcry_mac_hd_t* ctx = (gcry_mac_hd_t*)hmac_context;
if (ctx) { if (ctx) {
gcry_mac_close(*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) { int cp_sha512_digest_init(void **digest_context, void *) {
(void) user_data;
gcry_md_hd_t* ctx = (gcry_md_hd_t*)malloc(sizeof(gcry_mac_hd_t)); gcry_md_hd_t* ctx = (gcry_md_hd_t*)malloc(sizeof(gcry_mac_hd_t));
if (!ctx) return SG_ERR_NOMEM; if (!ctx) return SG_ERR_NOMEM;
@ -290,9 +272,7 @@ int cp_sha512_digest_init(void **digest_context, void *user_data) {
return SG_SUCCESS; return SG_SUCCESS;
} }
int cp_sha512_digest_update(void *digest_context, const uint8_t *data, size_t data_len, void *user_data) { int cp_sha512_digest_update(void *digest_context, const uint8_t *data, size_t data_len, void *) {
(void) user_data;
gcry_md_hd_t* ctx = (gcry_md_hd_t*)digest_context; gcry_md_hd_t* ctx = (gcry_md_hd_t*)digest_context;
gcry_md_write(*ctx, data, data_len); 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; return SG_SUCCESS;
} }
int cp_sha512_digest_final(void *digest_context, struct signal_buffer **output, void *user_data) { int cp_sha512_digest_final(void *digest_context, struct signal_buffer **output, void *) {
(void) user_data;
size_t len = gcry_md_get_algo_dlen(GCRY_MD_SHA512); size_t len = gcry_md_get_algo_dlen(GCRY_MD_SHA512);
gcry_md_hd_t* ctx = (gcry_md_hd_t*)digest_context; 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; return SG_SUCCESS;
} }
void cp_sha512_digest_cleanup(void *digest_context, void *user_data) { void cp_sha512_digest_cleanup(void *digest_context, void *) {
(void) user_data;
gcry_md_hd_t* ctx = (gcry_md_hd_t*)digest_context; gcry_md_hd_t* ctx = (gcry_md_hd_t*)digest_context;
if (ctx) { if (ctx) {
gcry_md_close(*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 *key, size_t key_len,
const uint8_t *iv, size_t iv_len, const uint8_t *iv, size_t iv_len,
const uint8_t *plaintext, size_t plaintext_len, const uint8_t *plaintext, size_t plaintext_len,
void *user_data) { void *) {
(void) user_data;
int algo, mode, error_code = SG_ERR_UNKNOWN; int algo, mode, error_code = SG_ERR_UNKNOWN;
if (aes_cipher(cipher, key_len, &algo, &mode)) return SG_ERR_INVAL; 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 *key, size_t key_len,
const uint8_t *iv, size_t iv_len, const uint8_t *iv, size_t iv_len,
const uint8_t *ciphertext, size_t ciphertext_len, const uint8_t *ciphertext, size_t ciphertext_len,
void *user_data) { void *) {
(void) user_data;
int algo, mode, error_code = SG_ERR_UNKNOWN; int algo, mode, error_code = SG_ERR_UNKNOWN;
*output = 0; *output = 0;
if (aes_cipher(cipher, key_len, &algo, &mode)) return SG_ERR_INVAL; 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 k_local_public_key = mdb_val_str("local_public_key");
MDB_val v_local_private_key, v_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_printf(NULL, "%sxmpp: failed to open lmdb transaction",
weechat_prefix("error")); weechat_prefix("error"));
return -1; 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) && &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)) &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); *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 else
{ {
struct ratchet_identity_key_pair *identity; auto identity = libsignal::identity_key_pair::generate(omemo->context);
signal_protocol_key_helper_generate_identity_key_pair( auto private_key = identity.get_private();
&identity, omemo->context.get()); auto public_key = identity.get_public();
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);
ec_private_key_serialize(private_data, private_key); ec_private_key_serialize(private_data, private_key);
ec_public_key_serialize(public_data, public_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); v_local_public_key.mv_size = signal_buffer_len(*public_data);
mdb_txn_abort(transaction); 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_printf(NULL, "%sxmpp: failed to open lmdb transaction",
weechat_prefix("error")); weechat_prefix("error"));
return -1; 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) || &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)) &k_local_public_key, &v_local_public_key, MDB_NOOVERWRITE))
{ {
weechat_printf(NULL, "%sxmpp: failed to write lmdb value", 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); v_local_private_key.mv_size);
*public_data = signal_buffer_create((const uint8_t*)v_local_public_key.mv_data, *public_data = signal_buffer_create((const uint8_t*)v_local_public_key.mv_data,
v_local_public_key.mv_size); v_local_public_key.mv_size);
omemo->identity.reset(identity);
omemo->identity = identity;
} }
return 0; 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); MDB_val v_local_registration_id = mdb_val_sizeof(uint32_t);
// Return the local client's registration ID // 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_printf(NULL, "%sxmpp: failed to open lmdb transaction",
weechat_prefix("error")); weechat_prefix("error"));
return -1; return -1;
} }
if (!mdb_get(transaction, omemo->db.dbi_omemo, if (!mdb_get(transaction, omemo->dbi.omemo,
&k_local_registration_id, &k_local_registration_id,
&v_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; uint32_t generated_id;
signal_protocol_key_helper_generate_registration_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; v_local_registration_id.mv_data = &generated_id;
mdb_txn_abort(transaction); 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_printf(NULL, "%sxmpp: failed to open lmdb transaction",
weechat_prefix("error")); weechat_prefix("error"));
return -1; return -1;
} }
if (mdb_put(transaction, omemo->db.dbi_omemo, if (mdb_put(transaction, omemo->dbi.omemo,
&k_local_registration_id, &k_local_registration_id,
&v_local_registration_id, MDB_NOOVERWRITE)) &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, snprintf((char*)k_identity_key.mv_data, k_identity_key.mv_size + 1,
"identity_key_%s_%u", address->name, address->device_id); "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_printf(NULL, "%sxmpp: failed to open lmdb transaction",
weechat_prefix("error")); weechat_prefix("error"));
return -1; 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)) { &v_identity_key, 0)) {
weechat_printf(NULL, "%sxmpp: failed to write lmdb value", weechat_printf(NULL, "%sxmpp: failed to write lmdb value",
weechat_prefix("error")); 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, snprintf((char*)k_identity_key.mv_data, k_identity_key.mv_size + 1,
"identity_key_%s_%u", address->name, address->device_id); "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_printf(NULL, "%sxmpp: failed to open lmdb transaction",
weechat_prefix("error")); weechat_prefix("error"));
return -1; 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)) { &v_identity_key)) {
weechat_printf(NULL, "%sxmpp: failed to read lmdb value", weechat_printf(NULL, "%sxmpp: failed to read lmdb value",
weechat_prefix("error")); 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, snprintf((char*)k_pre_key.mv_data, k_pre_key.mv_size + 1,
"pre_key_%-10u", pre_key_id); "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_printf(NULL, "%sxmpp: failed to open lmdb transaction",
weechat_prefix("error")); weechat_prefix("error"));
return -1; 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)) { &v_pre_key, 0)) {
weechat_printf(NULL, "%sxmpp: failed to write lmdb value", weechat_printf(NULL, "%sxmpp: failed to write lmdb value",
weechat_prefix("error")); 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, snprintf((char*)k_pre_key.mv_data, k_pre_key.mv_size + 1,
"pre_key_%-10u", pre_key_id); "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_printf(NULL, "%sxmpp: failed to open lmdb transaction",
weechat_prefix("error")); weechat_prefix("error"));
return -1; 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)) { &v_pre_key)) {
weechat_printf(NULL, "%sxmpp: failed to read lmdb value", weechat_printf(NULL, "%sxmpp: failed to read lmdb value",
weechat_prefix("error")); 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 k_pre_key_idx = mdb_val_str("pre_key_idx");
MDB_val v_pre_key_idx = mdb_val_intptr(&count); 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_printf(NULL, "%sxmpp: failed to open lmdb transaction",
weechat_prefix("error")); weechat_prefix("error"));
return -1; 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)) &k_pre_key_idx, &v_pre_key_idx))
{ {
if (increment) if (increment)
count += PRE_KEY_COUNT; 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)) &k_pre_key_idx, &v_pre_key_idx, 0))
{ {
weechat_printf(NULL, "%sxmpp: failed to read lmdb value", 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, snprintf((char*)k_pre_key.mv_data, k_pre_key.mv_size + 1,
"pre_key_%-10u", pre_key_id); "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_printf(NULL, "%sxmpp: failed to open lmdb transaction",
weechat_prefix("error")); weechat_prefix("error"));
return -1; return -1;
} }
if (!mdb_get(transaction, omemo->db.dbi_omemo, if (!mdb_get(transaction, omemo->dbi.omemo,
&k_pre_key, &v_pre_key)) &k_pre_key, &v_pre_key))
{ {
*record = signal_buffer_create((const uint8_t*)v_pre_key.mv_data, v_pre_key.mv_size); *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, for (signal_protocol_key_helper_generate_pre_keys(&pre_keys_list,
pks_get_count(omemo, 1), PRE_KEY_COUNT, 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_keys_list = signal_protocol_key_helper_key_list_next(pre_keys_list))
{ {
pre_key = signal_protocol_key_helper_key_list_element(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, snprintf((char*)k_pre_key.mv_data, k_pre_key.mv_size + 1,
"pre_key_%-10u", pre_key_id); "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_printf(NULL, "%sxmpp: failed to open lmdb transaction",
weechat_prefix("error")); weechat_prefix("error"));
return -1; 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)) { &v_pre_key)) {
weechat_printf(NULL, "%sxmpp: failed to erase lmdb value", weechat_printf(NULL, "%sxmpp: failed to erase lmdb value",
weechat_prefix("error")); 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, snprintf((char*)k_signed_pre_key.mv_data, k_signed_pre_key.mv_size + 1,
"signed_pre_key_%-10u", signed_pre_key_id); "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_printf(NULL, "%sxmpp: failed to open lmdb transaction",
weechat_prefix("error")); weechat_prefix("error"));
return -1; 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)) &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); *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; session_signed_pre_key *signed_pre_key = NULL;
struct signal_buffer *serialized_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); 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_data = signal_buffer_data(serialized_key);
v_signed_pre_key.mv_size = signal_buffer_len(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)) &k_signed_pre_key, &v_signed_pre_key, MDB_NOOVERWRITE))
{ {
weechat_printf(NULL, "%sxmpp: failed to read lmdb value", 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, snprintf((char*)k_signed_pre_key.mv_data, k_signed_pre_key.mv_size + 1,
"signed_pre_key_%-10u", signed_pre_key_id); "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_printf(NULL, "%sxmpp: failed to open lmdb transaction",
weechat_prefix("error")); weechat_prefix("error"));
return -1; 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)) { &v_signed_pre_key, 0)) {
weechat_printf(NULL, "%sxmpp: failed to write lmdb value", weechat_printf(NULL, "%sxmpp: failed to write lmdb value",
weechat_prefix("error")); 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, snprintf((char*)k_signed_pre_key.mv_data, k_signed_pre_key.mv_size + 1,
"signed_pre_key_%-10u", signed_pre_key_id); "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_printf(NULL, "%sxmpp: failed to open lmdb transaction",
weechat_prefix("error")); weechat_prefix("error"));
return -1; 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)) { &v_signed_pre_key)) {
mdb_txn_abort(transaction); mdb_txn_abort(transaction);
goto cleanup; 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, snprintf((char*)k_signed_pre_key.mv_data, k_signed_pre_key.mv_size + 1,
"signed_pre_key_%-10u", signed_pre_key_id); "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_printf(NULL, "%sxmpp: failed to open lmdb transaction",
weechat_prefix("error")); weechat_prefix("error"));
return -1; 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)) { &v_signed_pre_key)) {
weechat_printf(NULL, "%sxmpp: failed to erase lmdb value", weechat_printf(NULL, "%sxmpp: failed to erase lmdb value",
weechat_prefix("error")); 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, snprintf((char*)k_user.mv_data, k_user.mv_size + 1,
"user_%u_%s", address->device_id, address->name); "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_printf(NULL, "%sxmpp: failed to open lmdb transaction",
weechat_prefix("error")); weechat_prefix("error"));
return -1; return -1;
} }
if (mdb_get(transaction, omemo->db.dbi_omemo, if (mdb_get(transaction, omemo->dbi.omemo,
&k_session, &v_session)/* || &k_session, &v_session)/* ||
mdb_get(transaction, omemo->db.dbi_omemo, mdb_get(transaction, omemo->dbi.omemo,
&k_user, &v_user)*/) &k_user, &v_user)*/)
{ {
mdb_txn_abort(transaction); 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, snprintf((char*)k_device_ids.mv_data, k_device_ids.mv_size + 1,
"device_ids_%s", name); "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_printf(NULL, "%sxmpp: failed to open lmdb transaction",
weechat_prefix("error")); weechat_prefix("error"));
return -1; return -1;
} }
if (!mdb_get(transaction, omemo->db.dbi_omemo, if (!mdb_get(transaction, omemo->dbi.omemo,
&k_device_ids, &v_device_ids)) &k_device_ids, &v_device_ids))
{ {
char **argv; 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, snprintf((char*)k_user.mv_data, k_user.mv_size + 1,
"user_%u_%s", address->device_id, address->name); "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_printf(NULL, "%sxmpp: failed to open lmdb transaction",
weechat_prefix("error")); weechat_prefix("error"));
return -1; return -1;
} }
if (mdb_put(transaction, omemo->db.dbi_omemo, if (mdb_put(transaction, omemo->dbi.omemo,
&k_session, &v_session, 0)/* || &k_session, &v_session, 0)/* ||
mdb_put(transaction, omemo->db.dbi_omemo, mdb_put(transaction, omemo->dbi.omemo,
&k_user, &v_user, 0)*/) { &k_user, &v_user, 0)*/) {
weechat_printf(NULL, "%sxmpp: failed to write lmdb value", weechat_printf(NULL, "%sxmpp: failed to write lmdb value",
weechat_prefix("error")); 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, snprintf((char*)k_session.mv_data, k_session.mv_size + 1,
"session_%u_%s", address->device_id, address->name); "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_printf(NULL, "%sxmpp: failed to open lmdb transaction",
weechat_prefix("error")); weechat_prefix("error"));
return 0; 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); mdb_txn_abort(transaction);
return 0; 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, snprintf((char*)k_session.mv_data, k_session.mv_size + 1,
"session_%u_%s", address->device_id, address->name); "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_printf(NULL, "%sxmpp: failed to open lmdb transaction",
weechat_prefix("error")); weechat_prefix("error"));
return -1; 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_printf(NULL, "%sxmpp: failed to erase lmdb value",
weechat_prefix("error")); weechat_prefix("error"));
goto cleanup; 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, snprintf((char*)k_device_ids.mv_data, k_device_ids.mv_size + 1,
"device_ids_%s", sender_key_name->sender.name); "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_printf(NULL, "%sxmpp: failed to open lmdb transaction",
weechat_prefix("error")); weechat_prefix("error"));
return -1; return -1;
} }
if (!mdb_get(transaction, omemo->db.dbi_omemo, if (!mdb_get(transaction, omemo->dbi.omemo,
&k_device_ids, &v_device_ids)) &k_device_ids, &v_device_ids))
{ {
char **argv; 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; 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)/* || &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)*/ || &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)) { &k_device_ids, &v_device_ids, 0)) {
weechat_printf(NULL, "%sxmpp: failed to write lmdb value", weechat_printf(NULL, "%sxmpp: failed to write lmdb value",
weechat_prefix("error")); 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.device_id,
sender_key_name->sender.name); 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_printf(NULL, "%sxmpp: failed to open lmdb transaction",
weechat_prefix("error")); weechat_prefix("error"));
return -1; return -1;
} }
if (mdb_get(transaction, omemo->db.dbi_omemo, if (mdb_get(transaction, omemo->dbi.omemo,
&k_sender_key, &v_sender_key)/* && &k_sender_key, &v_sender_key)/* &&
mdb_get(transaction, omemo->db.dbi_omemo, mdb_get(transaction, omemo->dbi.omemo,
&k_user, &v_user)*/) &k_user, &v_user)*/)
{ {
*record = signal_buffer_create((const uint8_t*)v_sender_key.mv_data, v_sender_key.mv_size); *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); v_devicelist.mv_size = strlen((const char*)v_devicelist.mv_data);
for (char **device = (char **)devices; *device; device++) free(*device); 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_printf(NULL, "%sxmpp: failed to open lmdb transaction",
weechat_prefix("error")); weechat_prefix("error"));
return -1; return -1;
} }
if (mdb_put(transaction, omemo->db.dbi_omemo, &k_devicelist, if (mdb_put(transaction, omemo->dbi.omemo, &k_devicelist,
&v_devicelist, 0)) { &v_devicelist, 0)) {
weechat_printf(NULL, "%sxmpp: failed to write lmdb value", weechat_printf(NULL, "%sxmpp: failed to write lmdb value",
weechat_prefix("error")); weechat_prefix("error"));
@ -1639,33 +1610,13 @@ cleanup:
int dls_load_devicelist(signal_int_list **devicelist, const char *jid, t_omemo *omemo) int dls_load_devicelist(signal_int_list **devicelist, const char *jid, t_omemo *omemo)
{ {
MDB_txn *transaction = NULL; auto transaction = lmdb::txn::begin(omemo->db_env);
MDB_val k_devicelist = { std::string k_devicelist = fmt::format("devicelist_{}", jid);
.mv_size = strlen("devicelist_") + strlen(jid), std::string_view v_devicelist;
.mv_data = NULL, omemo->dbi.omemo.get(transaction, k_devicelist, v_devicelist);
};
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);
int devices_len = 0; int devices_len = 0;
char **devices = weechat_string_split((const char*)v_devicelist.mv_data, ";", NULL, 0, 0, &devices_len); char **devices = weechat_string_split(v_devicelist.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;
}
*devicelist = signal_int_list_alloc(); *devicelist = signal_int_list_alloc();
for (int i = 0; i < devices_len; i++) 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); weechat_string_free_split(devices);
if (mdb_txn_commit(transaction)) { transaction.commit();
weechat_printf(NULL, "%sxmpp: failed to close lmdb transaction",
weechat_prefix("error"));
goto cleanup;
};
return 0; return 0;
cleanup:
mdb_txn_abort(transaction);
return -1;
} }
int bks_store_bundle(struct signal_protocol_address *address, 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, snprintf(signed_pre_key_buffers[i], keylen + 1,
"%s.%s", signed_pre_key->id, signed_pre_key->public_key); "%s.%s", signed_pre_key->id, signed_pre_key->public_key);
int ret;
uint8_t *signing_key_buf; uint8_t *signing_key_buf;
size_t signing_key_len = base64_decode(identity_key, size_t signing_key_len = base64_decode(identity_key,
strlen(identity_key), &signing_key_buf); strlen(identity_key), &signing_key_buf);
ec_public_key *signing_key; libsignal::public_key signing_key(signing_key_buf,
if ((ret = curve_decode_point(&signing_key, signing_key_buf, signing_key_len, omemo->context);
signing_key_len, omemo->context.get()))) {
weechat_printf(NULL, "%sxmpp: failed to decode ED25519 prekey",
weechat_prefix("error"));
return -1;
};
uint8_t *signed_key_buf; uint8_t *signed_key_buf;
size_t signed_key_len = base64_decode(signed_pre_key->public_key, size_t signed_key_len = base64_decode(signed_pre_key->public_key,
strlen(signed_pre_key->public_key), &signed_key_buf); 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, .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_printf(NULL, "%sxmpp: failed to open lmdb transaction",
weechat_prefix("error")); weechat_prefix("error"));
return -1; return -1;
} }
int ret; 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)) || &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)) || &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)) || &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))) { &v_bundle_ik, 0))) {
weechat_printf(NULL, "%sxmpp: failed to write lmdb value '%s'@%u: %s", 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)); 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; MDB_val v_bundle_ik;
int ret; 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_printf(NULL, "%sxmpp: failed to open lmdb transaction",
weechat_prefix("error")); weechat_prefix("error"));
return -1; return -1;
@ -1880,13 +1819,13 @@ int bks_load_bundle(session_pre_key_bundle **bundle, struct signal_protocol_addr
struct signal_buffer *signature; struct signal_buffer *signature;
uint8_t *key_buf; size_t key_len; 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)) || &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)) || &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)) || &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))) &k_bundle_ik, &v_bundle_ik)))
{ {
goto cleanup; 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; char *key_data = (char *)memchr(bundle_pk, '.', 10 + 1) + 1;
uint8_t *key_buf; uint8_t *key_buf;
size_t key_len = base64_decode(key_data, strlen(key_data), &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_printf(NULL, "%sxmpp: failed to decode ED25519 prekey",
weechat_prefix("error")); weechat_prefix("error"));
goto cleanup; 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; char *key_data = (char *)memchr(bundle_sk, '.', 10 + 1) + 1;
uint8_t *key_buf; uint8_t *key_buf;
size_t key_len = base64_decode(key_data, strlen(key_data), &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_printf(NULL, "%sxmpp: failed to decode ED25519 signed prekey",
weechat_prefix("error")); weechat_prefix("error"));
goto cleanup; 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); 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); 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); 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_printf(NULL, "%sxmpp: failed to decode ED25519 identity key",
weechat_prefix("error")); weechat_prefix("error"));
goto cleanup; goto cleanup;
@ -1987,7 +1926,7 @@ xmpp_stanza_t *omemo::get_bundle(xmpp_ctx_t *context, char *from, char *to)
else num_keys++; else num_keys++;
session_pre_key *pre_key = NULL; session_pre_key *pre_key = NULL;
session_pre_key_deserialize(&pre_key, signal_buffer_data(record), 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))++; if (pre_key == 0) (*((int*)0))++;
signal_buffer_free(record); signal_buffer_free(record);
keypair = session_pre_key_get_key_pair(pre_key); 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 *signed_pre_key;
session_signed_pre_key_deserialize(&signed_pre_key, session_signed_pre_key_deserialize(&signed_pre_key,
signal_buffer_data(record), signal_buffer_len(record), signal_buffer_data(record), signal_buffer_len(record),
omemo->context.get()); omemo->context);
signal_buffer_free(record); signal_buffer_free(record);
uint32_t signed_pre_key_id = session_signed_pre_key_get_id(signed_pre_key); 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); 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) 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; auto omemo = this;
struct signal_context *context; omemo->context.create(buffer);
signal_context_create(&context, buffer); omemo->context.set_log_function(&log_emit_weechat);
omemo->context.reset(context);
signal_context_set_log_function(omemo->context.get(), &log_emit_weechat);
try { try {
omemo->db_path = std::shared_ptr<char>( omemo->db_path = std::shared_ptr<char>(
@ -2092,22 +2030,21 @@ void omemo::init(struct t_gui_buffer *buffer, const char *account_name)
NULL, NULL, NULL), NULL, NULL, NULL),
&free).get(); &free).get();
lmdb::env &env = omemo->db.env; lmdb::env &env = omemo->db_env;
env = lmdb::env::create(); env = lmdb::env::create();
env.open(omemo->db_path.data(), MDB_NOSUBDIR, 0664);
env.set_max_dbs(50); env.set_max_dbs(50);
env.set_mapsize((size_t)1048576 * 8000); // 8000MB map for valgrind env.set_mapsize((size_t)1048576 * 8000); // 8000MB map for valgrind
env.open(omemo->db_path.data(), MDB_NOSUBDIR, 0664); env.open(omemo->db_path.data(), MDB_NOSUBDIR, 0664);
lmdb::txn parentTransaction(nullptr); lmdb::txn parentTransaction{nullptr};
lmdb::txn transaction = lmdb::txn::begin(omemo->db.env, parentTransaction); lmdb::txn transaction = lmdb::txn::begin(omemo->db_env, parentTransaction);
std::string db_name = fmt::format("omemo_{}", account_name); 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(); transaction.commit();
} catch (const std::exception& ex) { } 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")); weechat_printf(NULL, format.data(), weechat_prefix("error"));
return; return;
} }
@ -2127,12 +2064,10 @@ void omemo::init(struct t_gui_buffer *buffer, const char *account_name)
.user_data = omemo, .user_data = omemo,
}; };
signal_context_set_crypto_provider(omemo->context.get(), &crypto_provider); omemo->context.set_crypto_provider(&crypto_provider);
signal_context_set_locking_functions(omemo->context.get(), &lock_function, &unlock_function); omemo->context.set_locking_functions(&lock_function, &unlock_function);
struct signal_protocol_store_context *store_context; omemo->store_context.create(omemo->context);
signal_protocol_store_context_create(&store_context, omemo->context.get());
omemo->store_context.reset(store_context);
struct signal_protocol_identity_key_store identity_key_store = { struct signal_protocol_identity_key_store identity_key_store = {
.get_identity_key_pair = &iks_get_identity_key_pair, .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, .user_data = omemo,
}; };
signal_protocol_store_context_set_identity_key_store( omemo->store_context.set_identity_key_store(&identity_key_store);
omemo->store_context.get(), &identity_key_store);
struct signal_protocol_pre_key_store pre_key_store = { struct signal_protocol_pre_key_store pre_key_store = {
.load_pre_key = &pks_load_pre_key, .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, .user_data = omemo,
}; };
signal_protocol_store_context_set_pre_key_store( omemo->store_context.set_pre_key_store(&pre_key_store);
omemo->store_context.get(), &pre_key_store);
struct signal_protocol_signed_pre_key_store signed_pre_key_store = { struct signal_protocol_signed_pre_key_store signed_pre_key_store = {
.load_signed_pre_key = &spks_load_signed_pre_key, .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, .user_data = omemo,
}; };
signal_protocol_store_context_set_signed_pre_key_store( omemo->store_context.set_signed_pre_key_store(&signed_pre_key_store);
omemo->store_context.get(), &signed_pre_key_store);
struct signal_protocol_session_store session_store = { struct signal_protocol_session_store session_store = {
.load_session_func = &ss_load_session_func, .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, .user_data = omemo,
}; };
signal_protocol_store_context_set_session_store( omemo->store_context.set_session_store(&session_store);
omemo->store_context.get(), &session_store);
struct signal_protocol_sender_key_store sender_key_store = { struct signal_protocol_sender_key_store sender_key_store = {
.store_sender_key = &sks_store_sender_key, .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, .user_data = omemo,
}; };
signal_protocol_store_context_set_sender_key_store( omemo->store_context.set_sender_key_store(&sender_key_store);
omemo->store_context.get(), &sender_key_store);
struct signal_buffer *public_data, *private_data; struct signal_buffer *public_data, *private_data;
iks_get_local_registration_id(omemo, &omemo->device_id); iks_get_local_registration_id(omemo, &omemo->device_id);
if (!iks_get_identity_key_pair(&public_data, &private_data, omemo)) if (!iks_get_identity_key_pair(&public_data, &private_data, omemo))
{ {
struct ec_public_key *public_key = NULL; libsignal::public_key public_key(signal_buffer_data(public_data),
struct ec_private_key *private_key = NULL; signal_buffer_len(public_data), omemo->context);
curve_decode_point(&public_key, signal_buffer_data(public_data), libsignal::private_key private_key(signal_buffer_data(private_data),
signal_buffer_len(public_data), omemo->context.get()); signal_buffer_len(private_data), omemo->context);
curve_decode_private_point(&private_key, signal_buffer_data(private_data), omemo->identity.create(public_key, private_key);
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);
} }
weechat_printf(buffer, "%somemo: device = %d", weechat_printf(buffer, "%somemo: device = %d",
weechat_prefix("info"), omemo->device_id); 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 = { struct signal_protocol_address address = {
.name = jid, .name_len = strlen(jid), .device_id = (int32_t)device_id }; .name = jid, .name_len = strlen(jid), .device_id = (int32_t)device_id };
{ {
ec_public_key *key;
uint8_t *key_buf; uint8_t *key_buf;
size_t key_len = base64_decode(identity_key, size_t key_len = base64_decode(identity_key,
strlen(identity_key), &key_buf); strlen(identity_key), &key_buf);
curve_decode_point(&key, key_buf, key_len, omemo->context.get()); libsignal::public_key key(key_buf, key_len, omemo->context);
signal_protocol_identity_save_identity(omemo->store_context.get(), signal_protocol_identity_save_identity(omemo->store_context,
&address, key); &address, key);
} }
bks_store_bundle(&address, pre_keys, signed_pre_keys, 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) { if (key_prekey) {
pre_key_signal_message *pre_key_message = NULL; pre_key_signal_message *pre_key_message = NULL;
if ((ret = pre_key_signal_message_deserialize(&pre_key_message, 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); 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 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); //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; signal_buffer_len(identity_buf), omemo))) return NULL;
struct session_cipher *cipher; struct session_cipher *cipher;
if ((ret = session_cipher_create(&cipher, omemo->store_context.get(), if ((ret = session_cipher_create(&cipher, omemo->store_context,
&address, omemo->context.get()))) return NULL; &address, omemo->context))) return NULL;
if ((ret = session_cipher_decrypt_pre_key_signal_message(cipher, if ((ret = session_cipher_decrypt_pre_key_signal_message(cipher,
pre_key_message, pre_key_message,
0, &aes_key))) return NULL; 0, &aes_key))) return NULL;
} else { } else {
if ((ret = signal_message_deserialize(&key_message, 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; struct session_cipher *cipher;
if ((ret = session_cipher_create(&cipher, omemo->store_context.get(), if ((ret = session_cipher_create(&cipher, omemo->store_context,
&address, omemo->context.get()))) return NULL; &address, omemo->context))) return NULL;
if ((ret = session_cipher_decrypt_signal_message(cipher, key_message, if ((ret = session_cipher_decrypt_signal_message(cipher, key_message,
0, &aes_key))) return NULL; 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++) for (size_t i = 0; i < signal_int_list_size(devicelist); i++)
{ {
uint32_t device_id = signal_int_list_at(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 = { struct signal_protocol_address address = {
.name = target, .name_len = strlen(target), .device_id = (int32_t)device_id}; .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; struct session_builder *builder = NULL;
if (((ret = ss_contains_session_func(&address, omemo))) <= 0) 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 = 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; if ((ret = session_builder_process_pre_key_bundle(builder, bundle))) continue;
} }
struct session_cipher *cipher; 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; struct ciphertext_message *signal_message;
if ((ret = session_cipher_encrypt(cipher, key_and_tag, AES_KEY_SIZE+tag_len, &signal_message))) continue; if ((ret = session_cipher_encrypt(cipher, key_and_tag, AES_KEY_SIZE+tag_len, &signal_message))) continue;
@ -2545,6 +2472,7 @@ xmpp_stanza_t *omemo::encode(struct t_account *account, const char *jid,
xmpp_stanza_add_child(header, header__key); xmpp_stanza_add_child(header, header__key);
xmpp_stanza_release(header__key); xmpp_stanza_release(header__key);
if (target == jid)
keycount++; keycount++;
signal_buffer_free(record); signal_buffer_free(record);
@ -2558,7 +2486,10 @@ xmpp_stanza_t *omemo::encode(struct t_account *account, const char *jid,
} }
free(key_and_tag); 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_t *header__iv = xmpp_stanza_new(account->context);
xmpp_stanza_set_name(header__iv, "iv"); xmpp_stanza_set_name(header__iv, "iv");

@ -29,10 +29,10 @@ struct omemo
libsignal::context context; libsignal::context context;
libsignal::store_context store_context; libsignal::store_context store_context;
struct { lmdb::env db_env = nullptr;
lmdb::env env; struct dbi {
lmdb::dbi dbi_omemo; lmdb::dbi omemo;
} db; } dbi;
std::string db_path; std::string db_path;
libsignal::identity_key_pair identity; libsignal::identity_key_pair identity;

@ -4,9 +4,17 @@
#pragma once #pragma once
#include <fmt/core.h>
#include <memory> #include <memory>
#include <functional> #include <functional>
#include <type_traits>
#include <signal_protocol.h> #include <signal_protocol.h>
#include <key_helper.h>
#include <session_builder.h>
#include <session_cipher.h>
#include <session_pre_key.h>
#include <protocol.h>
#include <curve.h>
namespace libsignal { namespace libsignal {
@ -15,43 +23,201 @@ namespace libsignal {
void operator() (T *ptr) { SIGNAL_UNREF(ptr); } void operator() (T *ptr) { SIGNAL_UNREF(ptr); }
}; };
template<> template<typename T>
struct deleter<struct signal_context> { using object = std::unique_ptr<T, deleter<T>>;
void operator() (struct signal_context *ptr)
{ signal_context_destroy(ptr); } template<typename T, typename CFun, typename DFun,
CFun &f_create, DFun &f_destroy, typename Base = T>
class type {
private:
T *_ptr;
public:
typedef T* pointer_type;
inline explicit type() : _ptr(nullptr) {
}
template<typename... Args>
inline explicit type(Args&&... args) : type() {
f_create(&_ptr, std::forward<Args>(args)...);
}
inline ~type() {
if (_ptr)
f_destroy(reinterpret_cast<Base*>(_ptr));
_ptr = nullptr;
}
template<typename... Args>
inline void create(Args&&... args) {
if (_ptr)
f_destroy(reinterpret_cast<Base*>(_ptr));
_ptr = nullptr;
f_create(&_ptr, std::forward<Args>(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<typename Fun, Fun &func, int success = 0, typename... Args,
typename = std::enable_if_t<std::is_same_v<int, std::invoke_result_t<Fun, pointer_type, Args...>>>>
inline void call(Args&&... args) {
int ret = func(*this, std::forward<Args>(args)...);
if (ret != success) throw std::runtime_error(
fmt::format("Signal Error: expected {}, was {}", success, ret));
}
template<typename Fun, Fun &func, typename... Args,
typename = std::enable_if_t<!std::is_same_v<int, std::invoke_result_t<Fun, pointer_type, Args...>>>>
inline std::invoke_result<Fun, pointer_type, Args...>::type
call(Args&&... args) {
return func(*this, std::forward<Args>(args)...);
}
}; };
template<> typedef type<struct signal_context,
struct deleter<struct signal_protocol_store_context> { decltype(signal_context_create), decltype(signal_context_destroy),
void operator() (struct signal_protocol_store_context *ptr) signal_context_create, signal_context_destroy> context_type;
{ signal_protocol_store_context_destroy(ptr); } 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<decltype(signal_context_set_log_function),
signal_context_set_log_function>(args...);
}
inline auto set_crypto_provider(auto &&...args) {
return call<decltype(signal_context_set_crypto_provider),
signal_context_set_crypto_provider>(args...);
}
inline auto set_locking_functions(auto &&...args) {
return call<decltype(signal_context_set_locking_functions),
signal_context_set_locking_functions>(args...);
}
}; };
template<> typedef type<struct signal_protocol_store_context,
struct deleter<struct ratchet_identity_key_pair> { decltype(signal_protocol_store_context_create),
void operator() (struct ratchet_identity_key_pair *ptr) decltype(signal_protocol_store_context_destroy),
{ ratchet_identity_key_pair_destroy( signal_protocol_store_context_create,
reinterpret_cast<signal_type_base*>(ptr)); } signal_protocol_store_context_destroy> 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<decltype(signal_protocol_store_context_set_identity_key_store),
signal_protocol_store_context_set_identity_key_store>(args...);
}
inline auto set_pre_key_store(auto &&...args) {
return call<decltype(signal_protocol_store_context_set_pre_key_store),
signal_protocol_store_context_set_pre_key_store>(args...);
}
inline auto set_signed_pre_key_store(auto &&...args) {
return call<decltype(signal_protocol_store_context_set_signed_pre_key_store),
signal_protocol_store_context_set_signed_pre_key_store>(args...);
}
inline auto set_session_store(auto &&...args) {
return call<decltype(signal_protocol_store_context_set_session_store),
signal_protocol_store_context_set_session_store>(args...);
}
inline auto set_sender_key_store(auto &&...args) {
return call<decltype(signal_protocol_store_context_set_sender_key_store),
signal_protocol_store_context_set_sender_key_store>(args...);
}
}; };
template<typename T> typedef type<struct ec_public_key,
using object = std::unique_ptr<T, deleter<T>>; decltype(curve_decode_point),
decltype(ec_public_key_destroy),
curve_decode_point,
ec_public_key_destroy,
signal_type_base> public_key_type;
class public_key : public public_key_type {
public:
using public_key_type::public_key_type;
template<typename T, typename... Args> inline static public_key deserialize(auto &&...args) {
object<T> make(int (*fun)(T**,Args...), Args... args) { pointer_type pointer;
T *result; ec_public_key_deserialize(&pointer, args...);
fun(&result, args...); return public_key(pointer);
return object<T>(result); }
inline auto serialize(auto &&...args) {
return call<decltype(ec_public_key_serialize),
ec_public_key_serialize>(args...);
}
friend class identity_key_pair;
}; };
typedef object<struct signal_context> context; typedef type<struct ec_private_key,
decltype(curve_decode_private_point),
decltype(ec_private_key_destroy),
curve_decode_private_point,
ec_private_key_destroy,
signal_type_base> private_key_type;
class private_key : public private_key_type {
public:
using private_key_type::private_key_type;
typedef object<struct signal_protocol_store_context> store_context; inline static private_key deserialize(auto &&...args) {
pointer_type pointer;
ec_private_key_deserialize(&pointer, args...);
return private_key(pointer);
}
typedef object<struct ratchet_identity_key_pair> identity_key_pair; inline auto serialize(auto &&...args) {
return call<decltype(ec_private_key_serialize),
ec_private_key_serialize>(args...);
}
friend class identity_key_pair;
};
typedef object<struct ec_public_key> public_key; typedef type<struct ratchet_identity_key_pair,
decltype(ratchet_identity_key_pair_create),
decltype(ratchet_identity_key_pair_destroy),
ratchet_identity_key_pair_create,
ratchet_identity_key_pair_destroy,
signal_type_base> 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<struct ec_private_key> private_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);
}
inline public_key get_public(auto &&...args) {
return call<decltype(ratchet_identity_key_pair_get_public),
ratchet_identity_key_pair_get_public>(args...);
}
inline private_key get_private(auto &&...args) {
return call<decltype(ratchet_identity_key_pair_get_private),
ratchet_identity_key_pair_get_private>(args...);
}
};
} }

Loading…
Cancel
Save