mirror of
https://github.com/profanity-im/profanity.git
synced 2024-11-03 19:37:16 -05:00
Permanently store pre keys
This commit is contained in:
parent
0d0e2b246a
commit
5cd2b8dc9d
@ -27,7 +27,7 @@
|
||||
|
||||
static gboolean loaded;
|
||||
|
||||
static void omemo_generate_short_term_crypto_materials(ProfAccount *account);
|
||||
static void omemo_publish_crypto_materials(ProfAccount *account);
|
||||
static void load_identity(void);
|
||||
static void load_sessions(void);
|
||||
static void lock(void *user_data);
|
||||
@ -210,7 +210,7 @@ omemo_on_connect(ProfAccount *account)
|
||||
|
||||
if (g_key_file_load_from_file(omemo_ctx.identity_keyfile, omemo_ctx.identity_filename->str, G_KEY_FILE_KEEP_COMMENTS, &error)) {
|
||||
load_identity();
|
||||
omemo_generate_short_term_crypto_materials(account);
|
||||
omemo_publish_crypto_materials(account);
|
||||
} else if (error->code != G_FILE_ERROR_NOENT) {
|
||||
log_warning("OMEMO: error loading identity from: %s, %s", omemo_ctx.identity_filename->str, error->message);
|
||||
return;
|
||||
@ -255,37 +255,32 @@ omemo_generate_crypto_materials(ProfAccount *account)
|
||||
}
|
||||
|
||||
log_info("Generate long term OMEMO cryptography metarials");
|
||||
|
||||
/* Device ID */
|
||||
gcry_randomize(&omemo_ctx.device_id, 4, GCRY_VERY_STRONG_RANDOM);
|
||||
omemo_ctx.device_id &= 0x7fffffff;
|
||||
g_key_file_set_uint64(omemo_ctx.identity_keyfile, OMEMO_STORE_GROUP_IDENTITY, OMEMO_STORE_KEY_DEVICE_ID, omemo_ctx.device_id);
|
||||
log_info("OMEMO: device id: %d", omemo_ctx.device_id);
|
||||
|
||||
/* Identity key */
|
||||
signal_protocol_key_helper_generate_identity_key_pair(&omemo_ctx.identity_key_pair, omemo_ctx.signal);
|
||||
signal_protocol_key_helper_generate_registration_id(&omemo_ctx.registration_id, 0, omemo_ctx.signal);
|
||||
|
||||
ec_public_key_serialize(&omemo_ctx.identity_key_store.public, ratchet_identity_key_pair_get_public(omemo_ctx.identity_key_pair));
|
||||
ec_private_key_serialize(&omemo_ctx.identity_key_store.private, ratchet_identity_key_pair_get_private(omemo_ctx.identity_key_pair));
|
||||
|
||||
g_key_file_set_uint64(omemo_ctx.identity_keyfile, OMEMO_STORE_GROUP_IDENTITY, OMEMO_STORE_KEY_DEVICE_ID, omemo_ctx.device_id);
|
||||
g_key_file_set_uint64(omemo_ctx.identity_keyfile, OMEMO_STORE_GROUP_IDENTITY, OMEMO_STORE_KEY_REGISTRATION_ID, omemo_ctx.registration_id);
|
||||
char *identity_key_public = g_base64_encode(signal_buffer_data(omemo_ctx.identity_key_store.public), signal_buffer_len(omemo_ctx.identity_key_store.public));
|
||||
g_key_file_set_string(omemo_ctx.identity_keyfile, OMEMO_STORE_GROUP_IDENTITY, OMEMO_STORE_KEY_IDENTITY_KEY_PUBLIC, identity_key_public);
|
||||
g_free(identity_key_public);
|
||||
|
||||
ec_private_key_serialize(&omemo_ctx.identity_key_store.private, ratchet_identity_key_pair_get_private(omemo_ctx.identity_key_pair));
|
||||
char *identity_key_private = g_base64_encode(signal_buffer_data(omemo_ctx.identity_key_store.private), signal_buffer_len(omemo_ctx.identity_key_store.private));
|
||||
g_key_file_set_string(omemo_ctx.identity_keyfile, OMEMO_STORE_GROUP_IDENTITY, OMEMO_STORE_KEY_IDENTITY_KEY_PRIVATE, identity_key_private);
|
||||
g_free(identity_key_private);
|
||||
|
||||
omemo_identity_keyfile_save();
|
||||
/* Registration ID */
|
||||
signal_protocol_key_helper_generate_registration_id(&omemo_ctx.registration_id, 0, omemo_ctx.signal);
|
||||
g_key_file_set_uint64(omemo_ctx.identity_keyfile, OMEMO_STORE_GROUP_IDENTITY, OMEMO_STORE_KEY_REGISTRATION_ID, omemo_ctx.registration_id);
|
||||
|
||||
omemo_generate_short_term_crypto_materials(account);
|
||||
}
|
||||
|
||||
static void
|
||||
omemo_generate_short_term_crypto_materials(ProfAccount *account)
|
||||
{
|
||||
/* Pre keys */
|
||||
unsigned int start;
|
||||
|
||||
log_info("Generate short term OMEMO cryptography metarials");
|
||||
|
||||
gcry_randomize(&start, sizeof(unsigned int), GCRY_VERY_STRONG_RANDOM);
|
||||
signal_protocol_key_helper_pre_key_list_node *pre_keys_head;
|
||||
signal_protocol_key_helper_generate_pre_keys(&pre_keys_head, start, 100, omemo_ctx.signal);
|
||||
@ -297,6 +292,7 @@ omemo_generate_short_term_crypto_materials(ProfAccount *account)
|
||||
}
|
||||
signal_protocol_key_helper_key_list_free(pre_keys_head);
|
||||
|
||||
/* Signed pre key */
|
||||
session_signed_pre_key *signed_pre_key;
|
||||
struct timeval tv;
|
||||
gettimeofday(&tv, NULL);
|
||||
@ -307,8 +303,16 @@ omemo_generate_short_term_crypto_materials(ProfAccount *account)
|
||||
signal_protocol_signed_pre_key_store_key(omemo_ctx.store, signed_pre_key);
|
||||
SIGNAL_UNREF(signed_pre_key);
|
||||
|
||||
omemo_identity_keyfile_save();
|
||||
|
||||
loaded = TRUE;
|
||||
|
||||
omemo_publish_crypto_materials(account);
|
||||
}
|
||||
|
||||
static void
|
||||
omemo_publish_crypto_materials(ProfAccount *account)
|
||||
{
|
||||
/* Ensure we get our current device list, and it gets updated with our
|
||||
* device_id */
|
||||
g_hash_table_insert(omemo_ctx.device_list_handler, strdup(account->jid), handle_own_device_list);
|
||||
@ -378,7 +382,12 @@ omemo_signed_prekey(unsigned char **output, size_t *length)
|
||||
session_signed_pre_key *signed_pre_key;
|
||||
signal_buffer *buffer = NULL;
|
||||
|
||||
signal_protocol_signed_pre_key_load_key(omemo_ctx.store, &signed_pre_key, omemo_ctx.signed_pre_key_id);
|
||||
if (signal_protocol_signed_pre_key_load_key(omemo_ctx.store, &signed_pre_key, omemo_ctx.signed_pre_key_id) != SG_SUCCESS) {
|
||||
*output = NULL;
|
||||
*length = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
ec_public_key_serialize(&buffer, ec_key_pair_get_public(session_signed_pre_key_get_key_pair(signed_pre_key)));
|
||||
SIGNAL_UNREF(signed_pre_key);
|
||||
*length = signal_buffer_len(buffer);
|
||||
@ -392,7 +401,12 @@ omemo_signed_prekey_signature(unsigned char **output, size_t *length)
|
||||
{
|
||||
session_signed_pre_key *signed_pre_key;
|
||||
|
||||
signal_protocol_signed_pre_key_load_key(omemo_ctx.store, &signed_pre_key, omemo_ctx.signed_pre_key_id);
|
||||
if (signal_protocol_signed_pre_key_load_key(omemo_ctx.store, &signed_pre_key, omemo_ctx.signed_pre_key_id) != SG_SUCCESS) {
|
||||
*output = NULL;
|
||||
*length = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
*length = session_signed_pre_key_get_signature_len(signed_pre_key);
|
||||
*output = malloc(*length);
|
||||
memcpy(*output, session_signed_pre_key_get_signature(signed_pre_key), *length);
|
||||
@ -1134,10 +1148,15 @@ static void
|
||||
load_identity(void)
|
||||
{
|
||||
log_info("Loading OMEMO identity");
|
||||
|
||||
/* Device ID */
|
||||
omemo_ctx.device_id = g_key_file_get_uint64(omemo_ctx.identity_keyfile, OMEMO_STORE_GROUP_IDENTITY, OMEMO_STORE_KEY_DEVICE_ID, NULL);
|
||||
log_info("OMEMO: device id: %d", omemo_ctx.device_id);
|
||||
|
||||
/* Registration ID */
|
||||
omemo_ctx.registration_id = g_key_file_get_uint64(omemo_ctx.identity_keyfile, OMEMO_STORE_GROUP_IDENTITY, OMEMO_STORE_KEY_REGISTRATION_ID, NULL);
|
||||
|
||||
/* Identity key */
|
||||
char *identity_key_public_b64 = g_key_file_get_string(omemo_ctx.identity_keyfile, OMEMO_STORE_GROUP_IDENTITY, OMEMO_STORE_KEY_IDENTITY_KEY_PUBLIC, NULL);
|
||||
size_t identity_key_public_len;
|
||||
unsigned char *identity_key_public = g_base64_decode(identity_key_public_b64, &identity_key_public_len);
|
||||
@ -1159,7 +1178,42 @@ load_identity(void)
|
||||
g_free(identity_key_public);
|
||||
g_free(identity_key_private);
|
||||
|
||||
char **keys = g_key_file_get_keys(omemo_ctx.identity_keyfile, OMEMO_STORE_GROUP_TRUST, NULL, NULL);
|
||||
char **keys = NULL;
|
||||
/* Pre keys */
|
||||
keys = g_key_file_get_keys(omemo_ctx.identity_keyfile, OMEMO_STORE_GROUP_PREKEYS, NULL, NULL);
|
||||
if (keys) {
|
||||
int i;
|
||||
for (i = 0; keys[i] != NULL; i++) {
|
||||
char *pre_key_b64 = g_key_file_get_string(omemo_ctx.identity_keyfile, OMEMO_STORE_GROUP_PREKEYS, keys[i], NULL);
|
||||
size_t pre_key_len;
|
||||
unsigned char *pre_key = g_base64_decode(pre_key_b64, &pre_key_len);
|
||||
g_free(pre_key_b64);
|
||||
signal_buffer *buffer = signal_buffer_create(pre_key, pre_key_len);
|
||||
g_free(pre_key);
|
||||
g_hash_table_insert(omemo_ctx.pre_key_store, GINT_TO_POINTER(strtoul(keys[i], NULL, 10)), buffer);
|
||||
}
|
||||
}
|
||||
g_strfreev(keys);
|
||||
|
||||
/* Signed pre keys */
|
||||
keys = g_key_file_get_keys(omemo_ctx.identity_keyfile, OMEMO_STORE_GROUP_SIGNED_PREKEYS, NULL, NULL);
|
||||
if (keys) {
|
||||
int i;
|
||||
for (i = 0; keys[i] != NULL; i++) {
|
||||
char *signed_pre_key_b64 = g_key_file_get_string(omemo_ctx.identity_keyfile, OMEMO_STORE_GROUP_SIGNED_PREKEYS, keys[i], NULL);
|
||||
size_t signed_pre_key_len;
|
||||
unsigned char *signed_pre_key = g_base64_decode(signed_pre_key_b64, &signed_pre_key_len);
|
||||
g_free(signed_pre_key_b64);
|
||||
signal_buffer *buffer = signal_buffer_create(signed_pre_key, signed_pre_key_len);
|
||||
g_free(signed_pre_key);
|
||||
g_hash_table_insert(omemo_ctx.signed_pre_key_store, GINT_TO_POINTER(strtoul(keys[i], NULL, 10)), buffer);
|
||||
omemo_ctx.signed_pre_key_id = strtoul(keys[i], NULL, 10);
|
||||
}
|
||||
}
|
||||
g_strfreev(keys);
|
||||
|
||||
/* Trusted keys */
|
||||
keys = g_key_file_get_keys(omemo_ctx.identity_keyfile, OMEMO_STORE_GROUP_TRUST, NULL, NULL);
|
||||
if (keys) {
|
||||
int i;
|
||||
for (i = 0; keys[i] != NULL; i++) {
|
||||
@ -1173,6 +1227,8 @@ load_identity(void)
|
||||
}
|
||||
}
|
||||
g_strfreev(keys);
|
||||
|
||||
loaded = TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -190,6 +190,16 @@ store_pre_key(uint32_t pre_key_id, uint8_t *record, size_t record_len,
|
||||
|
||||
signal_buffer *buffer = signal_buffer_create(record, record_len);
|
||||
g_hash_table_insert(pre_key_store, GINT_TO_POINTER(pre_key_id), buffer);
|
||||
|
||||
/* Long term storage */
|
||||
char *pre_key_id_str = g_strdup_printf("%d", pre_key_id);
|
||||
char *record_b64 = g_base64_encode(record, record_len);
|
||||
g_key_file_set_string(omemo_identity_keyfile(), OMEMO_STORE_GROUP_PREKEYS, pre_key_id_str, record_b64);
|
||||
g_free(pre_key_id_str);
|
||||
g_free(record_b64);
|
||||
|
||||
omemo_identity_keyfile_save();
|
||||
|
||||
return SG_SUCCESS;
|
||||
}
|
||||
|
||||
@ -206,7 +216,16 @@ remove_pre_key(uint32_t pre_key_id, void *user_data)
|
||||
{
|
||||
GHashTable *pre_key_store = (GHashTable *)user_data;
|
||||
|
||||
return g_hash_table_remove(pre_key_store, GINT_TO_POINTER(pre_key_id));
|
||||
int ret = g_hash_table_remove(pre_key_store, GINT_TO_POINTER(pre_key_id));
|
||||
|
||||
/* Long term storage */
|
||||
char *pre_key_id_str = g_strdup_printf("%d", pre_key_id);
|
||||
g_key_file_remove_key(omemo_identity_keyfile(), OMEMO_STORE_GROUP_PREKEYS, pre_key_id_str, NULL);
|
||||
g_free(pre_key_id_str);
|
||||
|
||||
omemo_identity_keyfile_save();
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int
|
||||
@ -233,6 +252,16 @@ store_signed_pre_key(uint32_t signed_pre_key_id, uint8_t *record,
|
||||
|
||||
signal_buffer *buffer = signal_buffer_create(record, record_len);
|
||||
g_hash_table_insert(signed_pre_key_store, GINT_TO_POINTER(signed_pre_key_id), buffer);
|
||||
|
||||
/* Long term storage */
|
||||
char *signed_pre_key_id_str = g_strdup_printf("%d", signed_pre_key_id);
|
||||
char *record_b64 = g_base64_encode(record, record_len);
|
||||
g_key_file_set_string(omemo_identity_keyfile(), OMEMO_STORE_GROUP_SIGNED_PREKEYS, signed_pre_key_id_str, record_b64);
|
||||
g_free(signed_pre_key_id_str);
|
||||
g_free(record_b64);
|
||||
|
||||
omemo_identity_keyfile_save();
|
||||
|
||||
return SG_SUCCESS;
|
||||
}
|
||||
|
||||
@ -249,7 +278,16 @@ remove_signed_pre_key(uint32_t signed_pre_key_id, void *user_data)
|
||||
{
|
||||
GHashTable *signed_pre_key_store = (GHashTable *)user_data;
|
||||
|
||||
return g_hash_table_remove(signed_pre_key_store, GINT_TO_POINTER(signed_pre_key_id));
|
||||
int ret = g_hash_table_remove(signed_pre_key_store, GINT_TO_POINTER(signed_pre_key_id));
|
||||
|
||||
/* Long term storage */
|
||||
char *signed_pre_key_id_str = g_strdup_printf("%d", signed_pre_key_id);
|
||||
g_key_file_remove_key(omemo_identity_keyfile(), OMEMO_STORE_GROUP_PREKEYS, signed_pre_key_id_str, NULL);
|
||||
g_free(signed_pre_key_id_str);
|
||||
|
||||
omemo_identity_keyfile_save();
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int
|
||||
@ -284,6 +322,7 @@ save_identity(const signal_protocol_address *address, uint8_t *key_data,
|
||||
signal_buffer *buffer = signal_buffer_create(key_data, key_len);
|
||||
g_hash_table_insert(identity_key_store->trusted, strdup(node), buffer);
|
||||
|
||||
/* Long term storage */
|
||||
char *key_b64 = g_base64_encode(key_data, key_len);
|
||||
g_key_file_set_string(omemo_identity_keyfile(), OMEMO_STORE_GROUP_TRUST, node, key_b64);
|
||||
g_free(key_b64);
|
||||
|
@ -3,6 +3,8 @@
|
||||
#include "config.h"
|
||||
|
||||
#define OMEMO_STORE_GROUP_IDENTITY "identity"
|
||||
#define OMEMO_STORE_GROUP_PREKEYS "prekeys"
|
||||
#define OMEMO_STORE_GROUP_SIGNED_PREKEYS "signed_prekeys"
|
||||
#define OMEMO_STORE_GROUP_TRUST "trust"
|
||||
#define OMEMO_STORE_KEY_DEVICE_ID "device_id"
|
||||
#define OMEMO_STORE_KEY_REGISTRATION_ID "registration_id"
|
||||
|
Loading…
Reference in New Issue
Block a user