diff options
-rw-r--r-- | plugins/omemo/src/module.vala | 199 |
1 files changed, 93 insertions, 106 deletions
diff --git a/plugins/omemo/src/module.vala b/plugins/omemo/src/module.vala index 67651be5..728251f0 100644 --- a/plugins/omemo/src/module.vala +++ b/plugins/omemo/src/module.vala @@ -256,7 +256,7 @@ public class Module : XmppStreamModule { public void start_session_with(XmppStream stream, string bare_jid, int device_id) { print(@"Asking for bundle from $bare_jid/$device_id\n"); - stream.get_module(Pubsub.Module.IDENTITY).request(stream, bare_jid, @"$NODE_BUNDLES:$device_id", new OtherBundleResponseListener(store, device_id)); + stream.get_module(Pubsub.Module.IDENTITY).request(stream, bare_jid, @"$NODE_BUNDLES:$device_id", on_other_bundle_result, Tuple.create(store, device_id)); } public void ignore_device(string jid, int32 device_id) { @@ -276,129 +276,116 @@ public class Module : XmppStreamModule { } } - private class OtherBundleResponseListener : Pubsub.RequestResponseListener, Object { - private Store store; - private int device_id; - - public OtherBundleResponseListener(Store store, int device_id) { - this.store = store; - this.device_id = device_id; - } - - public void on_result(XmppStream stream, string jid, string? id, StanzaNode? node) { - bool fail = false; - if (node == null) { - // Device not registered, shouldn't exist + private static void on_other_bundle_result(XmppStream stream, string jid, string? id, StanzaNode? node, Object? storage) { + Tuple<Store, int> tuple = (Tuple<Store, int>)storage; + Store store = tuple.a; + int device_id = tuple.b; + + bool fail = false; + if (node == null) { + // Device not registered, shouldn't exist + fail = true; + } else { + Bundle bundle = new Bundle(node); + int32 signed_pre_key_id = bundle.signed_pre_key_id; + ECPublicKey? signed_pre_key = bundle.signed_pre_key; + uint8[] signed_pre_key_signature = bundle.signed_pre_key_signature; + ECPublicKey? identity_key = bundle.identity_key; + + ArrayList<Bundle.PreKey> pre_keys = bundle.pre_keys; + int pre_key_idx = Random.int_range(0, pre_keys.size); + int32 pre_key_id = pre_keys[pre_key_idx].key_id; + ECPublicKey? pre_key = pre_keys[pre_key_idx].key; + + if (signed_pre_key_id < 0 || signed_pre_key == null || identity_key == null || pre_key_id < 0 || pre_key == null) { fail = true; } else { - Bundle bundle = new Bundle(node); - int32 signed_pre_key_id = bundle.signed_pre_key_id; - ECPublicKey? signed_pre_key = bundle.signed_pre_key; - uint8[] signed_pre_key_signature = bundle.signed_pre_key_signature; - ECPublicKey? identity_key = bundle.identity_key; - - ArrayList<Bundle.PreKey> pre_keys = bundle.pre_keys; - int pre_key_idx = Random.int_range(0, pre_keys.size); - int32 pre_key_id = pre_keys[pre_key_idx].key_id; - ECPublicKey? pre_key = pre_keys[pre_key_idx].key; - - if (signed_pre_key_id < 0 || signed_pre_key == null || identity_key == null || pre_key_id < 0 || pre_key == null) { - fail = true; - } else { - Address address = new Address(); - address.name = jid; - address.device_id = device_id; - try { - if (store.contains_session(address)) { - return; - } - SessionBuilder builder = store.create_session_builder(address); - builder.process_pre_key_bundle(create_pre_key_bundle(device_id, device_id, pre_key_id, pre_key, signed_pre_key_id, signed_pre_key, signed_pre_key_signature, identity_key)); - } catch (Error e) { - fail = true; + Address address = new Address(); + address.name = jid; + address.device_id = device_id; + try { + if (store.contains_session(address)) { + return; } - address.device_id = 0; // TODO: Hack to have address obj live longer - get_module(stream).session_started(jid, device_id); + SessionBuilder builder = store.create_session_builder(address); + builder.process_pre_key_bundle(create_pre_key_bundle(device_id, device_id, pre_key_id, pre_key, signed_pre_key_id, signed_pre_key, signed_pre_key_signature, identity_key)); + } catch (Error e) { + fail = true; } - } - if (fail) { - get_module(stream).ignore_device(jid, device_id); + address.device_id = 0; // TODO: Hack to have address obj live longer + get_module(stream).session_started(jid, device_id); } } + if (fail) { + get_module(stream).ignore_device(jid, device_id); + } } public void publish_bundles_if_needed(XmppStream stream, string jid) { - stream.get_module(Pubsub.Module.IDENTITY).request(stream, jid, @"$NODE_BUNDLES:$(store.local_registration_id)", new SelfBundleResponseListener(store)); + stream.get_module(Pubsub.Module.IDENTITY).request(stream, jid, @"$NODE_BUNDLES:$(store.local_registration_id)", on_self_bundle_result, store); } - private class SelfBundleResponseListener : Pubsub.RequestResponseListener, Object { - private Store store; - - public SelfBundleResponseListener(Store store) { - this.store = store; - } - - public void on_result(XmppStream stream, string jid, string? id, StanzaNode? node) { - Map<int, ECPublicKey> keys = new HashMap<int, ECPublicKey>(); - ECPublicKey identity_key = null; - IdentityKeyPair identity_key_pair = null; - int32 signed_pre_key_id = -1; - ECPublicKey signed_pre_key = null; - SignedPreKeyRecord signed_pre_key_record = null; - bool changed = false; - if (node == null) { - identity_key = store.identity_key_pair.public; - changed = true; - } else { - Bundle bundle = new Bundle(node); - foreach (Bundle.PreKey prekey in bundle.pre_keys) { - keys[prekey.key_id] = prekey.key; - } - identity_key = bundle.identity_key; - signed_pre_key_id = bundle.signed_pre_key_id;; - signed_pre_key = bundle.signed_pre_key; + private static void on_self_bundle_result(XmppStream stream, string jid, string? id, StanzaNode? node, Object? storage) { + Store store = (Store)storage; + Map<int, ECPublicKey> keys = new HashMap<int, ECPublicKey>(); + ECPublicKey identity_key = null; + IdentityKeyPair identity_key_pair = null; + int32 signed_pre_key_id = -1; + ECPublicKey signed_pre_key = null; + SignedPreKeyRecord signed_pre_key_record = null; + bool changed = false; + if (node == null) { + identity_key = store.identity_key_pair.public; + changed = true; + } else { + Bundle bundle = new Bundle(node); + foreach (Bundle.PreKey prekey in bundle.pre_keys) { + keys[prekey.key_id] = prekey.key; } + identity_key = bundle.identity_key; + signed_pre_key_id = bundle.signed_pre_key_id;; + signed_pre_key = bundle.signed_pre_key; + } - // Validate IdentityKey - if (store.identity_key_pair.public.compare(identity_key) != 0) { - changed = true; - } - identity_key_pair = store.identity_key_pair; - - // Validate signedPreKeyRecord + ID - if (signed_pre_key_id == -1 || !store.contains_signed_pre_key(signed_pre_key_id) || store.load_signed_pre_key(signed_pre_key_id).key_pair.public.compare(signed_pre_key) != 0) { - signed_pre_key_id = Random.int_range(1, int32.MAX); // TODO: No random, use ordered number - signed_pre_key_record = context.generate_signed_pre_key(identity_key_pair, signed_pre_key_id); - store.store_signed_pre_key(signed_pre_key_record); - changed = true; - } else { - signed_pre_key_record = store.load_signed_pre_key(signed_pre_key_id); - } + // Validate IdentityKey + if (store.identity_key_pair.public.compare(identity_key) != 0) { + changed = true; + } + identity_key_pair = store.identity_key_pair; + + // Validate signedPreKeyRecord + ID + if (signed_pre_key_id == -1 || !store.contains_signed_pre_key(signed_pre_key_id) || store.load_signed_pre_key(signed_pre_key_id).key_pair.public.compare(signed_pre_key) != 0) { + signed_pre_key_id = Random.int_range(1, int32.MAX); // TODO: No random, use ordered number + signed_pre_key_record = context.generate_signed_pre_key(identity_key_pair, signed_pre_key_id); + store.store_signed_pre_key(signed_pre_key_record); + changed = true; + } else { + signed_pre_key_record = store.load_signed_pre_key(signed_pre_key_id); + } - // Validate PreKeys - Set<PreKeyRecord> pre_key_records = new HashSet<PreKeyRecord>(); - foreach (var entry in keys.entries) { - if (store.contains_pre_key(entry.key)) { - PreKeyRecord record = store.load_pre_key(entry.key); - if (record.key_pair.public.compare(entry.value) == 0) { - pre_key_records.add(record); - } + // Validate PreKeys + Set<PreKeyRecord> pre_key_records = new HashSet<PreKeyRecord>(); + foreach (var entry in keys.entries) { + if (store.contains_pre_key(entry.key)) { + PreKeyRecord record = store.load_pre_key(entry.key); + if (record.key_pair.public.compare(entry.value) == 0) { + pre_key_records.add(record); } } - int new_keys = NUM_KEYS_TO_PUBLISH - pre_key_records.size; - if (new_keys > 0) { - int32 next_id = Random.int_range(1, int32.MAX); // TODO: No random, use ordered number - Set<PreKeyRecord> new_records = context.generate_pre_keys((uint)next_id, (uint)new_keys); - pre_key_records.add_all(new_records); - foreach (PreKeyRecord record in new_records) { - store.store_pre_key(record); - } - changed = true; + } + int new_keys = NUM_KEYS_TO_PUBLISH - pre_key_records.size; + if (new_keys > 0) { + int32 next_id = Random.int_range(1, int32.MAX); // TODO: No random, use ordered number + Set<PreKeyRecord> new_records = context.generate_pre_keys((uint)next_id, (uint)new_keys); + pre_key_records.add_all(new_records); + foreach (PreKeyRecord record in new_records) { + store.store_pre_key(record); } + changed = true; + } - if (changed) { - publish_bundles(stream, signed_pre_key_record, identity_key_pair, pre_key_records, (int32) store.local_registration_id); - } + if (changed) { + publish_bundles(stream, signed_pre_key_record, identity_key_pair, pre_key_records, (int32) store.local_registration_id); } } |