Smack OMEMO Support

Start implementing OMEMO for aTalk, needs some advice on the following:

During aTalk OMEMO implementation, found that the following method;

OmemoManager getInstanceFor(XMPPConnection connection);

has to be called when XMPPConnection is connected i.e. callback connected(XMPPConnection connection) and not when authenticated(XMPPConnection connection, boolean resumed)

In the above getInstanceFor() method, it needs to retrieve the BareJid user; However in aTalk implementation, the connection and login occurs in two different processes, and user is not defined during connection process. Moving the execution of the above method when user is authenticated has conflict with OmemoManager#initialize() where it is also being called during authenticated();

Currently to overcome the above limitation, I have to create a private method as below:

private OmemoManager initOMemoManager(ProtocolProviderService pps) {
BareJid user;
XMPPTCPConnection connection = pps.getConnection();

if (connection.getUser() != null) {
user = connection.getUser().asBareJid();
} else {
user = pps.getAccountID().getFullJid().asBareJid();
}

int defaultDeviceId = OmemoService.getInstance().getOmemoStoreBackend().getDefaultDeviceId(user);

if (defaultDeviceId < 1) {
defaultDeviceId = OmemoManager.randomDeviceId();
OmemoService.getInstance().getOmemoStoreBackend().setDefaultDeviceId(user, defaultDeviceId);
}

return OmemoManager.getInstanceFor(connection, defaultDeviceId);
}

Is there other alternative to overcome the problem instead of the above private method approach.

Hi @cmeng!

I noticed, that the getInstanceFor(XMPPConnection) method of the OmemoManager is currently broken, which is quite annoying.

Until its fixed I’d suggest, that your client takes care of generating, storing and providing the deviceId of user accounts, since OmemoManager.getInstanceFor(XMPPConnection, deviceId) should work as intended. Calling getInstanceFor(XMPPConnection) should be avoided for now.

I think your method looks quite good to overcome the issue for now. I’ll see if I can push a fix during the week.

I hope this helps you

Did you manage to implement a solution to overcome the problem that occurs in aTalk scenario case; and a snapshot release that include your fix?

Unfortunately not yet. I’m quite busy right now, since I’m participating in the Google Summer of Code, so fixing the bug unfortunately has relatively low priority right now. I’m open for proposals how to fix the issue though and pull requests are obviously welcome .

When aTalk starts up with a empty sql omemo tables, the omemoDevice ID stored by the statement

      OmemoService.getInstance().getOmemoStoreBackend().setDefaultDeviceId(user, defaultDeviceId);

in the aTalk own implemented method above is not being used by OmemoManager. It was found that all subsequent access or creation of any omemo data e.g. preKey, signedPreKey, identities etc by OmemoManager uses a different omemoDevice with same bareJid but different deviceId.

See attached omemo sql tables. The unused omemoDevices are with currentSignedPreKeyId == 0 and lastPreKeyId == null.

With the exception of the unused omemoDevices being left in the sql table, all Omemo operations are working on aTalk.

Note:
Just uploaded an official release for aTalk version 0.8.2 to support OMEMO chat. Anybody who are interested to try out may download it from

http://atalk.sytes.net/releases/atalk-android/aTalk-release.apk