|
|
|
@ -4,6 +4,7 @@
|
|
|
|
|
|
|
|
|
|
#include <fmt/core.h>
|
|
|
|
|
#include <memory>
|
|
|
|
|
#include <stdexcept>
|
|
|
|
|
#include <stdlib.h>
|
|
|
|
|
#include <stdint.h>
|
|
|
|
|
#include <sys/param.h>
|
|
|
|
@ -11,13 +12,6 @@
|
|
|
|
|
#include <math.h>
|
|
|
|
|
#include <limits.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 <weechat/weechat-plugin.h>
|
|
|
|
|
|
|
|
|
@ -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<uint8_t[]>(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<char>(
|
|
|
|
@ -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");
|
|
|
|
|