Fix OMEMO plugin for latest changes
This commit is contained in:
parent
d5ea5172a7
commit
766af21d87
|
@ -256,7 +256,7 @@ public class Module : XmppStreamModule {
|
||||||
|
|
||||||
public void start_session_with(XmppStream stream, string bare_jid, int device_id) {
|
public void start_session_with(XmppStream stream, string bare_jid, int device_id) {
|
||||||
print(@"Asking for bundle from $bare_jid/$device_id\n");
|
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) {
|
public void ignore_device(string jid, int32 device_id) {
|
||||||
|
@ -276,129 +276,116 @@ public class Module : XmppStreamModule {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private class OtherBundleResponseListener : Pubsub.RequestResponseListener, Object {
|
private static void on_other_bundle_result(XmppStream stream, string jid, string? id, StanzaNode? node, Object? storage) {
|
||||||
private Store store;
|
Tuple<Store, int> tuple = (Tuple<Store, int>)storage;
|
||||||
private int device_id;
|
Store store = tuple.a;
|
||||||
|
int device_id = tuple.b;
|
||||||
|
|
||||||
public OtherBundleResponseListener(Store store, int device_id) {
|
bool fail = false;
|
||||||
this.store = store;
|
if (node == null) {
|
||||||
this.device_id = device_id;
|
// 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;
|
||||||
|
|
||||||
public void on_result(XmppStream stream, string jid, string? id, StanzaNode? node) {
|
ArrayList<Bundle.PreKey> pre_keys = bundle.pre_keys;
|
||||||
bool fail = false;
|
int pre_key_idx = Random.int_range(0, pre_keys.size);
|
||||||
if (node == null) {
|
int32 pre_key_id = pre_keys[pre_key_idx].key_id;
|
||||||
// Device not registered, shouldn't exist
|
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;
|
fail = true;
|
||||||
} else {
|
} else {
|
||||||
Bundle bundle = new Bundle(node);
|
Address address = new Address();
|
||||||
int32 signed_pre_key_id = bundle.signed_pre_key_id;
|
address.name = jid;
|
||||||
ECPublicKey? signed_pre_key = bundle.signed_pre_key;
|
address.device_id = device_id;
|
||||||
uint8[] signed_pre_key_signature = bundle.signed_pre_key_signature;
|
try {
|
||||||
ECPublicKey? identity_key = bundle.identity_key;
|
if (store.contains_session(address)) {
|
||||||
|
return;
|
||||||
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.device_id = 0; // TODO: Hack to have address obj live longer
|
SessionBuilder builder = store.create_session_builder(address);
|
||||||
get_module(stream).session_started(jid, device_id);
|
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.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);
|
if (fail) {
|
||||||
}
|
get_module(stream).ignore_device(jid, device_id);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void publish_bundles_if_needed(XmppStream stream, string jid) {
|
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 static void on_self_bundle_result(XmppStream stream, string jid, string? id, StanzaNode? node, Object? storage) {
|
||||||
private Store store;
|
Store store = (Store)storage;
|
||||||
|
Map<int, ECPublicKey> keys = new HashMap<int, ECPublicKey>();
|
||||||
public SelfBundleResponseListener(Store store) {
|
ECPublicKey identity_key = null;
|
||||||
this.store = store;
|
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;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void on_result(XmppStream stream, string jid, string? id, StanzaNode? node) {
|
// Validate IdentityKey
|
||||||
Map<int, ECPublicKey> keys = new HashMap<int, ECPublicKey>();
|
if (store.identity_key_pair.public.compare(identity_key) != 0) {
|
||||||
ECPublicKey identity_key = null;
|
changed = true;
|
||||||
IdentityKeyPair identity_key_pair = null;
|
}
|
||||||
int32 signed_pre_key_id = -1;
|
identity_key_pair = store.identity_key_pair;
|
||||||
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
|
// Validate signedPreKeyRecord + ID
|
||||||
if (store.identity_key_pair.public.compare(identity_key) != 0) {
|
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) {
|
||||||
changed = true;
|
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);
|
||||||
identity_key_pair = store.identity_key_pair;
|
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 signedPreKeyRecord + ID
|
// Validate PreKeys
|
||||||
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) {
|
Set<PreKeyRecord> pre_key_records = new HashSet<PreKeyRecord>();
|
||||||
signed_pre_key_id = Random.int_range(1, int32.MAX); // TODO: No random, use ordered number
|
foreach (var entry in keys.entries) {
|
||||||
signed_pre_key_record = context.generate_signed_pre_key(identity_key_pair, signed_pre_key_id);
|
if (store.contains_pre_key(entry.key)) {
|
||||||
store.store_signed_pre_key(signed_pre_key_record);
|
PreKeyRecord record = store.load_pre_key(entry.key);
|
||||||
changed = true;
|
if (record.key_pair.public.compare(entry.value) == 0) {
|
||||||
} else {
|
pre_key_records.add(record);
|
||||||
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);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
int new_keys = NUM_KEYS_TO_PUBLISH - pre_key_records.size;
|
}
|
||||||
if (new_keys > 0) {
|
int new_keys = NUM_KEYS_TO_PUBLISH - pre_key_records.size;
|
||||||
int32 next_id = Random.int_range(1, int32.MAX); // TODO: No random, use ordered number
|
if (new_keys > 0) {
|
||||||
Set<PreKeyRecord> new_records = context.generate_pre_keys((uint)next_id, (uint)new_keys);
|
int32 next_id = Random.int_range(1, int32.MAX); // TODO: No random, use ordered number
|
||||||
pre_key_records.add_all(new_records);
|
Set<PreKeyRecord> new_records = context.generate_pre_keys((uint)next_id, (uint)new_keys);
|
||||||
foreach (PreKeyRecord record in new_records) {
|
pre_key_records.add_all(new_records);
|
||||||
store.store_pre_key(record);
|
foreach (PreKeyRecord record in new_records) {
|
||||||
}
|
store.store_pre_key(record);
|
||||||
changed = true;
|
|
||||||
}
|
}
|
||||||
|
changed = true;
|
||||||
|
}
|
||||||
|
|
||||||
if (changed) {
|
if (changed) {
|
||||||
publish_bundles(stream, signed_pre_key_record, identity_key_pair, pre_key_records, (int32) store.local_registration_id);
|
publish_bundles(stream, signed_pre_key_record, identity_key_pair, pre_key_records, (int32) store.local_registration_id);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue