about summary refs log tree commit diff stats
diff options
context:
space:
mode:
authorPaul Fariello <paul@fariello.eu>2019-04-01 21:12:00 +0200
committerPaul Fariello <paul@fariello.eu>2019-04-10 17:23:46 +0200
commit0f4dd61776222202f614d88a0b3d565d88834f77 (patch)
tree8ecf04af013aa44a1b19fecef9a0d207bdc6ceca
parente69f947547160ea2c965a3d4f5966c5f4a289340 (diff)
downloadprofani-tty-0f4dd61776222202f614d88a0b3d565d88834f77.tar.gz
Ensure pre keys are generated if missing from long term storage
-rw-r--r--src/omemo/omemo.c75
1 files changed, 51 insertions, 24 deletions
diff --git a/src/omemo/omemo.c b/src/omemo/omemo.c
index 0515cbf9..2a7a50d8 100644
--- a/src/omemo/omemo.c
+++ b/src/omemo/omemo.c
@@ -28,6 +28,8 @@
 static gboolean loaded;
 
 static void omemo_publish_crypto_materials(ProfAccount *account);
+static void _generate_pre_keys(int count);
+static void _generate_signed_pre_key(void);
 static void load_identity(void);
 static void load_sessions(void);
 static void lock(void *user_data);
@@ -280,28 +282,10 @@ omemo_generate_crypto_materials(ProfAccount *account)
     g_key_file_set_uint64(omemo_ctx.identity_keyfile, OMEMO_STORE_GROUP_IDENTITY, OMEMO_STORE_KEY_REGISTRATION_ID, omemo_ctx.registration_id);
 
     /* Pre keys */
-    unsigned int start;
-    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);
-
-    signal_protocol_key_helper_pre_key_list_node *p;
-    for (p = pre_keys_head; p != NULL; p = signal_protocol_key_helper_key_list_next(p)) {
-        session_pre_key *prekey = signal_protocol_key_helper_key_list_element(p);
-        signal_protocol_pre_key_store_key(omemo_ctx.store, prekey);
-    }
-    signal_protocol_key_helper_key_list_free(pre_keys_head);
+    _generate_pre_keys(100);
 
     /* Signed pre key */
-    session_signed_pre_key *signed_pre_key;
-    struct timeval tv;
-    gettimeofday(&tv, NULL);
-    unsigned long long timestamp = (unsigned long long)(tv.tv_sec) * 1000 + (unsigned long long)(tv.tv_usec) / 1000;
-
-    omemo_ctx.signed_pre_key_id = 1;
-    signal_protocol_key_helper_generate_signed_pre_key(&signed_pre_key, omemo_ctx.identity_key_pair, omemo_ctx.signed_pre_key_id, timestamp, omemo_ctx.signal);
-    signal_protocol_signed_pre_key_store_key(omemo_ctx.store, signed_pre_key);
-    SIGNAL_UNREF(signed_pre_key);
+    _generate_signed_pre_key();
 
     omemo_identity_keyfile_save();
 
@@ -1179,10 +1163,11 @@ load_identity(void)
     g_free(identity_key_private);
 
     char **keys = NULL;
+    int i;
     /* Pre keys */
+    i = 0;
     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;
@@ -1192,13 +1177,19 @@ load_identity(void)
             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);
+    }
+
+    /* Ensure we have at least 100 pre keys */
+    if (i < 100) {
+        _generate_pre_keys(100 - i);
     }
-    g_strfreev(keys);
 
     /* Signed pre keys */
+    i = 0;
     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;
@@ -1209,8 +1200,12 @@ load_identity(void)
             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);
+    }
+
+    if (i == 0) {
+        _generate_signed_pre_key();
     }
-    g_strfreev(keys);
 
     /* Trusted keys */
     keys = g_key_file_get_keys(omemo_ctx.identity_keyfile, OMEMO_STORE_GROUP_TRUST, NULL, NULL);
@@ -1229,6 +1224,8 @@ load_identity(void)
     g_strfreev(keys);
 
     loaded = TRUE;
+
+    omemo_identity_keyfile_save();
 }
 
 static void
@@ -1289,3 +1286,33 @@ g_hash_table_free(GHashTable *hash_table)
     g_hash_table_remove_all(hash_table);
     g_hash_table_unref(hash_table);
 }
+
+static void
+_generate_pre_keys(int count)
+{
+    unsigned int start;
+    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, count, omemo_ctx.signal);
+
+    signal_protocol_key_helper_pre_key_list_node *p;
+    for (p = pre_keys_head; p != NULL; p = signal_protocol_key_helper_key_list_next(p)) {
+        session_pre_key *prekey = signal_protocol_key_helper_key_list_element(p);
+        signal_protocol_pre_key_store_key(omemo_ctx.store, prekey);
+    }
+    signal_protocol_key_helper_key_list_free(pre_keys_head);
+}
+
+static void
+_generate_signed_pre_key(void)
+{
+    session_signed_pre_key *signed_pre_key;
+    struct timeval tv;
+    gettimeofday(&tv, NULL);
+    unsigned long long timestamp = (unsigned long long)(tv.tv_sec) * 1000 + (unsigned long long)(tv.tv_usec) / 1000;
+
+    omemo_ctx.signed_pre_key_id = 1;
+    signal_protocol_key_helper_generate_signed_pre_key(&signed_pre_key, omemo_ctx.identity_key_pair, omemo_ctx.signed_pre_key_id, timestamp, omemo_ctx.signal);
+    signal_protocol_signed_pre_key_store_key(omemo_ctx.store, signed_pre_key);
+    SIGNAL_UNREF(signed_pre_key);
+}